Sql-Server

啟發我對索引的 INCLUDE

  • January 21, 2019

好吧,在閱讀了 Erik Darling 的文章Filtered Indexes: Just Add Includes之後,我對我如何使用 INCLUDES 感到非常好奇和難過:

他給出了一些關於 INCLUDE 的範例等,但我對他創建的實際索引感到困惑。

這是查詢:

SELECT Id, DisplayName
FROM   Users 
WHERE  Reputation > 400000;

我會做的是:

CREATE INDEX ix_bla on USERS (Reputation) 
INCLUDE (Id, DisplayName)

我認為我們應該使用WHERE索引中的內容,並INCLUDE使用SELECT.

但是 Erik 這樣做了:

CREATE UNIQUE NONCLUSTERED INDEX Users_400k_Club
ON dbo.Users ( DisplayName, Id )
INCLUDE ( Reputation )
WHERE Reputation > 400000
WITH ( DROP_EXISTING = ON );

這裡的問題不是過濾索引。我的問題是他為什麼在索引和包含子句中使用DISPLAYNAMEand ?ID``REPUTATION

並且只是為了一個簡單的測試,在具有數百萬行的表中執行此查詢以進行測試:

select COL1
     ,COL2
     ,COL3
from MyTable
   where COL2 > 4513516

SQL 告訴我創建這個索引:

CREATE NONCLUSTERED INDEX ix_nada
ON MyTable
   (
       [COL2]
   )
INCLUDE 
   (
       [COL1],
       [COL3]
   )
GO

您閱讀和所做的是否正確?

假設,您在使用者表上沒有索引,那麼

CREATE INDEX ix_bla on USERS (Reputation) 
INCLUDE (Id, DisplayName)
WHERE Reputation > 400000;

這個指數還可以。

但這不是@Erik 想要展示的重點。

根據那個部落格,假設你已經有任何這樣的索引,比如,

CREATE UNIQUE NONCLUSTERED INDEX Users_400k_Club
ON dbo.Users ( DisplayName, Id )

並且您需要在 Reputation 上創建過濾索引,然後只需在 Include 中提及它即可完成這項工作並避免創建昂貴的索引。

所以他拒絕這個,

CREATE UNIQUE NONCLUSTERED INDEX Users_400k_Club
ON dbo.Users ( DisplayName, Id )
INCLUDE ( Reputation )
WHERE Reputation > 400000
WITH ( DROP_EXISTING = ON );

過濾索引:只需添加包含Filtered Index這是他想要展示的新觀點。

Erik 的意圖不是表明以 DisplayName 開頭的索引是該查詢的 GOOD 索引。

他的觀點只是表明它會使用該索引。它正在執行掃描而不是搜尋,這在這種情況下並不是很好。

如果您真的想為部落格文章中的查詢創建一個完美的索引,您可以首先在 Reputation 上創建它作為鍵(因為 WHERE 子句在 Reputation 上。)

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