Sql-Server
覆蓋指數問題
我有以下查詢
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
僅用於避免查找(我喜歡稱其為“順風順水”)。當然總有例外:
- 由於大小,您不能總是在鍵中包含列;
- 由於基數,它可能無關緊要;要麼,
- 它可能不會影響計劃,因為您必須將它放在鍵中以允許索引繼續滿足其他查詢語義。
在某些情況下,
INCLUDE
d 列可以很好地滿足過濾器,並且在很多情況下更改索引可能有助於此特定查詢,但它可能會對您的其餘工作負載造成嚴重破壞。您應該始終針對代表盡可能多的完整業務週期的整個工作負載測試索引更改,而不是依賴缺失的索引 DMV 或您自己的分析,這些分析似乎專注於單個查詢。我相信 Paul White 會做出更詳盡、技術上更準確的回應。