Sql-Server

建議索引

  • October 23, 2019

我是一般索引的新手,剛剛開始學習查詢計劃等。我正在研究這個特定的查詢,它一直建議我創建以下索引:

CREATE NONCLUSTERED INDEX [<Name of Missing Index, sysname,>]
ON [dbo].[Company] ([CreatedById],[TenantId],[CreatedDate])

在此處輸入圖像描述

我已經創建了以下索引:

CREATE NONCLUSTERED INDEX [IX_Company_Tenant] 
ON [dbo].[Company] ([TenantId],[UserId],[CreatedDate])

我想知道的是,如果我將已經創建的索引更改為:

CREATE NONCLUSTERED INDEX [IX_Company_Tenant] 
ON [dbo].[Company] ([TenantId],[UserId],[CreatedDate], [CreatedByID])

而不是創建查詢儲存建議的索引?

編輯

即使在應用第三個索引之後:

CREATE NONCLUSTERED INDEX [IX_Company_Tenant] 
ON [dbo].[Company] ([TenantId],[UserId],[CreatedDate], [CreatedByID])

我仍然得到相同的建議索引。

首先,確保在創建索引之間轉儲該查詢的記憶體計劃。核心選項是執行記憶體刷新(DBCC FREEPROCCACHE),但您也可以查找計劃句柄並執行特定的句柄。我還建議在試驗它們之間刪除非聚集索引——如果你在這個表上有三個索引都試圖加速同一個查詢,那不是最好的情況。

在考慮創建索引時,請記住 SQL 為您提供的索引創建建議價值有限。當說“我可以在這裡使用索引做得更好”時,SQL 通常是正確的,但它確實沒有一個好的方法來告訴您最適合您需要的確切索引。

大多數情況下,它會給你一個次優的列順序。很多時候它會錯過有用的列,或者告訴你放太多。

通常,您希望對導致需要索引的查詢有充分的了解,然後創建索引以適應該查詢。大多數查詢採用歸位某些特定記錄集的形式,因此索引中的列按照最能歸位所需數據到最不能夠歸位的順序排列。換句話說,如果一列可以消除 95% 的所有可能結果,而另一列可以消除 20% 的結果,則將 95% 的列放在第一位。

舉個簡單的例子,如果我有一個查詢,它按日期選擇一小部分 (1%) 的記錄子集,並且還通過 50% 的標誌消除了一些剩餘的記錄,我會更好地訂購我的首先按日期索引列,然後再按標誌索引。反過來做會讓我為相同的最終結果做更多的工作。

在不知道您的數據的情況下查看您的查詢,我猜想它的一個很好的索引將是:

CREATE NONCLUSTERED INDEX [IX_Company_Tenant] 
ON [dbo].[Company] ([CreatedDate],[CreatedByID],[TenantId])

這是一篇很好的部落格文章,可以更深入地解釋它 - https://www.brentozar.com/archive/2019/10/how-to-think-like-the-sql-server-engine-adding-a-nonclustered -指數/

引用自:https://serverfault.com/questions/988337