Sql-Server
索引中關鍵列的順序
這個查詢的執行計劃似乎做出了一個非常糟糕的選擇(當然我知道它不是):
SELECT TOP 1 E_PER_ID FROM E WHERE E_CUS_ID = 1912 AND E_TYPE = 'R' ORDER BY E_ID DESC
兩個相關的指標是:
CREATE NONCLUSTERED INDEX IX_EMAIL_2 ON EMAIL (E_CUS_ID ASC, E_DATE_SENT ASC) WITH (FILLFACTOR = 95) CREATE NONCLUSTERED INDEX IX_EMAIL_3 ON EMAIL (E_ID ASC, E_TYPE ASC, E_CUS_ID ASC) INCLUDE (E_PER_ID) WITH (FILLFACTOR = 95)
查詢計劃選擇 IX_EMAIL_2。
看起來 IX_EMAIL_3 正在覆蓋,而 IX_EMAIL_2 顯然不是。
這僅僅是 b/c E_CUS_ID 鍵列在 IX_EMAIL_2 中的第一個嗎?
我不知道引擎會忽略完全覆蓋的索引,而支持僅包含一個所需列的索引,但該列在索引中是第一個。
注意:這個表有 121M 的記錄,所以我不能做太多的測試來看看我是否正確而無需等待幾個小時。
E_ID
在索引排序時不是WHERE
子句的一部分,因此 SQL 無法從 where 查找任何值,需要掃描索引以找到它。這就是為什麼它正在採取.IX_EMAIL_3``E_ID``IX_EMAIL_2
試試這個:
CREATE NONCLUSTERED INDEX IX_EMAIL_4 ON EMAIL (E_CUS_ID ASC, E_TYPE ASC, E_ID ASC) INCLUDE (E_PER_ID) WITH (FILLFACTOR = 95)
我認為它會被使用。
這是關於你的 WHERE 子句。我想尋找 E_CUS_ID ASC 所需的 IO 更少,而不是執行對聚集索引的查找以獲取失去的列並按 E_ID DESC 對其進行排序,因為掃描 E_CUS_ID = 1912 和 E_TYPE = ‘R’ 的整個第二個索引。