Sql-Server

覆蓋指數問題

  • May 6, 2019

我有以下查詢

Select  Pt.PRODID, PT.INVENTREFID,  Inv.ItemName, PT.ItemID, Configid,  Pt.QTYSCHED,
PT.DLVDATE,  Pt.CREATEDDATETIME, pt.SCHEDEND,
CASE Left(PT.INVENTREFID, 3)
    WHEN 'SJB' THEN ST.SALESNAME
    WHEN 'WJB' THEN 'Sub - Assembly'
    ELSE 'Stock'
 END as CustomerName
from Dynamicsv5Realtime.dbo.PRODTABLE PT
Join Dynamicsv5Realtime.dbo.Inventdim ID
On PT.InventdimId = ID.InventdimID
and PT.Dataareaid = ID.dataareaid
Join Dynamicsv5Realtime.dbo.INVENTTABLE Inv
On Inv.itemid = PT.ItemId
Left Join Dynamicsv5Realtime.dbo.SALESTABLE ST
ON ST.SalesId = PT.INVENTREFID
and ST.Dataareaid = PT.dataareaid
where pt.PRODSTATUS in(2,3,4)
and PT.DATAAREAID = 'AJB'
Order by 7 

當我想改進它時,我想出了以下索引

CREATE NONCLUSTERED INDEX [INDEX_2]
ON [dbo].[PRODTABLE] ([INVENTREFID],[DATAAREAID],[INVENTDIMID],[PRODSTATUS])
INCLUDE ([PRODID],[ItemID],[QTYSCHED],[DLVDATE],[CREATEDDATETIME],[SCHEDEND])

但是,這不如缺少索引 DMV 提出的以下有效

CREATE NONCLUSTERED INDEX [INDEX_1]
ON [dbo].[PRODTABLE] ([DATAAREAID],[PRODSTATUS])
INCLUDE ([ITEMID],[QTYSCHED],[DLVDATE],[SCHEDEND],[INVENTREFID],[PRODID],[INVENTDIMID],    [CREATEDDATETIME]) 

我想知道的是什麼時候將列放在索引本身而不是在索引的包含部分中更有效?

可能會感謝

非常普遍且非技術性地,如果要在WHERE子句中使用該列(或過濾/查找),並且INCLUDE僅用於避免查找(我喜歡稱其為“順風順水”)。當然總有例外:

  • 由於大小,您不能總是在鍵中包含列;
  • 由於基數,它可能無關緊要;要麼,
  • 它可能不會影響計劃,因為您必須將它放在鍵中以允許索引繼續滿足其他查詢語義。

在某些情況下,INCLUDEd 列可以很好地滿足過濾器,並且在很多情況下更改索引可能有助於此特定查詢,但它可能會對您的其餘工作負載造成嚴重破壞。您應該始終針對代表盡可能多的完整業務週期的整個工作負載測試索引更改,而不是依賴缺失的索引 DMV 或您自己的分析,這些分析似乎專注於單個查詢。

我相信 Paul White 會做出更詳盡、技術上更準確的回應。

引用自:https://dba.stackexchange.com/questions/36255