2013-09-25 31 views
3

我有一個基本的表,如下所示。優化我的SQL查詢 - 選擇正確的索引

create table Orders 
(
    ID INT IDENTITY(1,1) PRIMARY KEY, 
    Company VARCHAR(3), 
    ItemID INT, 
    BoxID INT, 
    OrderNum VARCHAR(5), 
    Status VARCHAR(5), 
    --about 10 more columns, varchars and ints and dates 
) 

我試圖優化我的所有SQL,因爲我得到一個公平的幾個死鎖和一些緩慢 - 但我對這種事情沒有專家!

我創建了幾個索引:
聚集在ID(主鍵)上。
非羣集上([條目標識號])
非羣集上([BoxID])
非羣集上索引指數指數([公司],[ORDERNUM],[狀態])
也許1或2更多在其他一些列

但我不是100%滿意的結果。

SELECT * FROM Orders WHERE ItemID=100 

給了我一個索引seek +一個鍵查找和一個嵌套循環(Inner join)。 我可以看到爲什麼 - 但不知道我是否應該做任何事情。他們的關鍵查找是97%的這批似乎不好!

每個使用的查詢都會拉回表中的每一列,但我不喜歡在索引中包含每一列的想法。

我正在進行更改以查詢在[Company]字段中的所有內容每個查詢都會使用它,因爲結果應該是從來沒有包含多於1個值。所以他們都會改變:

SELECT * FROM Orders WHERE ItemID=100 --Old 
SELECT * FROM Orders WHERE Company='a' and ItemID=100 --New 

但是,這樣的執行計劃給我完全一樣,不包括公司(這確實讓我感到吃驚!)。

  • 爲什麼兩個執行計劃高於相同? (我目前在[公司]沒有索引)

  • 是否值得將[公司]添加到我的所有索引,因爲它似乎使 與執行計劃有所不同?

  • 我是不是應該只給[公司]添加1個單一索引並保留原始索引? - 但是那個 是否意味着每個查詢都會有2個搜索?

  • 是否值得'包括'我的索引中的所有其他列以避免 密鑰查找? (使指數每噸更大,但可能 加快步伐?)即

    CREATE NONCLUSTERED INDEX [IX_Orders_MyIndex] ON [Orders] 
    ([Company] ASC, [OrderNum] ASC, [Status] ASC) 
    INCLUDE ([ID],[ItemID],[BoxID], 
    [Column5],[Column6],[Column7],[Column8],[Column9],[Column10],etc) 
    

,如果我做這件事是4個或5個指標顯得凌亂。

基本上我有4-5個經常運行的查詢(一些選擇和更新),所以我想盡可能地提高效率。 所有查詢將使用[公司]字段,並至少有一個其他字段。我應該如何去做。

任何幫助表示讚賞:)

+0

集羣idenx不應該在ID上,因爲您不需要查找ID順序什麼是您需要制定的是什麼是您的常見查詢 – Mark

+0

通過where子句company ='a'和ItemID = 100,優化器可以根據其數據庫統計信息自由選擇它所計算的最有效的索引。例如,如果您碰巧總共有1000條記錄,並且只有50家不同的公司,但有200個不同的ItemID,則優化器將決定採用ItemID,因爲每個ItemID的5條記錄看起來比每個公司的20條記錄的指標更好。 –

回答

3

在你執行計劃,你說,查找需要的批次的97%。

在這種情況下,它並不意味着什麼,因爲索引搜索速度非常快,而且您沒有太多的操作要完成。

該查找實際上是您根據您指定的索引讀取的記錄。

爲什麼兩個執行計劃高於相同? (我目前在[公司]沒有索引)

Non-Clustered index on ([Company],[OrderNum],[Status])

該指數將僅當CompanyOrderNumStatus出現在WHERE子句中予以考慮。

當只傳遞company時,級聯索引會生成一個看起來像這樣的0000000000000的密鑰,它會創建一個不完整的密鑰,該密鑰需要爲其他值使用通配符。

它看起來有點像這樣:key like 'XXX%'這個邏輯將需要一個耗時的索引掃描。

優化器將確定首選查找並從ItemID索引中找到行,然後掃描這些索引以匹配所需公司的任何索引。

是否值得將[公司]添加到我的所有索引,因爲它似乎使執行計劃與0不同?

你應該考慮有一個Company索引,而不是將它添加到所有的索引。 複合索引可以通過減少嵌套循環的數量來加快速度,但你必須徹底思考。

您添加到這樣的索引的字段的順序非常重要,它們應該按唯一性排序以允許更好的查找。此外,你不應該添加一個可能不會用在查詢中的字段。

我是不是應該給[公司]增加1個單一索引並保留原始索引? - 但這是否意味着每個查詢都會有2個查詢?

有多個索引查找並不是那麼糟糕,它們通常是並行的,只有兩者的結果匹配在一起。

是否值得'包括'我的索引中的所有其他列以避免密鑰查找? (使索引大一點,但可能會加快速度?)

這是值得的,只有幾個字段可以在where子句中可選,或者當您有查詢時只選擇那些字段使用指定的索引。

末票據

各項指標不相等,比較字符串(VARCHAR)是不一樣的比較數字(整數,日期時間,字節,等等)。

另外,保持它們的清潔效果非常有幫助,如果您的索引是零散的,那麼就性能增益而言,它們將毫無用處。