2014-02-26 55 views
8

我有我試圖優化刪除排序操作正確的SQL索引刪除排序

SELECT *,ROW_NUMBER() OVER (
     PARTITION BY RuleInstanceId 
     ORDER BY [Timestamp] DESC 
    ) AS rn 
FROM RuleInstanceHistoricalMembership 

一切我已閱讀(如:Optimizing SQL queries by removing Sort operator in Execution plan)SQL語句表明,這是正確的索引添加,但它似乎沒有任何作用。

CREATE NONCLUSTERED INDEX IX_MyIndex ON dbo.[RuleInstanceHistoricalMembership](RuleInstanceId, [Timestamp] DESC) 

enter image description here

我必須失去了一些東西。我讀過的文章堆這一切似乎sugguest指數跨越兩列應該解決這個問題

+1

當你改變'select *'爲'select RuleInstanceID,Timestamp' – iruvar

+0

@ 1_CR,使它消失,我需要索引跨越所有選定的列也? –

+1

對於select *,它基本上是優化器在非聚簇索引的每一行的聚簇索引查找和全表掃描之間的選擇 - 在選擇後者時可能是合理的。您可以通過「包含」列將所有其他列作爲「有效載荷」添加到非聚集索引中,以避免訪問聚集索引,但不知道更多關於數據量的信息等,很難知道這是否是明智的選擇 – iruvar

回答

8

技術上已添加做索引可以讓你避免排序。

但是,您創建的索引不覆蓋,因此SQL Server將需要執行6千萬個密鑰查找返回基表。

簡單地掃描聚集索引並在運行中對其進行排序的成本比該選項便宜得多。

爲了讓索引自動使用,你需要兩者之一。

  • 刪除查詢SELECT列中的列,以便索引覆蓋它。
  • INCLUDE-d列添加到索引。

BTW:對於6000萬行的表,你可能會發現,即使你試圖對非覆蓋索引生效的問題與索引提示你還沒有得到避免的預期效果一種排序。

CREATE TABLE RuleInstanceHistoricalMembership 
    (
    ID    INT PRIMARY KEY, 
    Col2   INT, 
    Col3   INT, 
    RuleInstanceId INT, 
    [Timestamp] INT 
) 

CREATE NONCLUSTERED INDEX IX_MyIndex 
    ON dbo.[RuleInstanceHistoricalMembership](RuleInstanceId, [Timestamp] DESC) 

/*Fake small table*/ 
UPDATE STATISTICS RuleInstanceHistoricalMembership 
        WITH ROWCOUNT = 600, 
         PAGECOUNT = 10 

SELECT *, 
     ROW_NUMBER() OVER (PARTITION BY RuleInstanceId 
           ORDER BY [Timestamp] DESC) AS rn 
FROM RuleInstanceHistoricalMembership WITH (INDEX = IX_MyIndex) 

給人的計劃

enter image description here

由於沒有排序,但構成該行和頁數

/*Fake large table*/ 
UPDATE STATISTICS RuleInstanceHistoricalMembership 
        WITH ROWCOUNT = 60000000, 
         PAGECOUNT = 10000000 

,然後再試一次,你會得到

enter image description here

現在它有兩種!

NCI上的掃描是RuleInstanceId, Timestamp DESC順序,但隨後SQL Server將其重新排列爲每Optimizing I/O Performance by Sorting的聚簇索引鍵順序(Id ASC)。

此步驟旨在嘗試將6000萬隨機查詢的預期大規模成本降低到聚集索引。然後它被分類回原來的RuleInstanceId, Timestamp DESC命令,該索引交付它。

+0

感謝堆這個答案,我有一堆更好的理解爲什麼SQL沒有選擇我的索引現在,非常感謝 –