Sql-Server
啟發我對索引的 INCLUDE
好吧,在閱讀了 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 );
這裡的問題不是過濾索引。我的問題是他為什麼在索引和包含子句中使用
DISPLAYNAME
and ?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 上。)