Sql-Server

索引中關鍵列的順序

  • January 14, 2022

這個查詢的執行計劃似乎做出了一個非常糟糕的選擇(當然我知道它不是):

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’ 的整個第二個索引。

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