Sql-Server

單獨的特定索引 VS 單一的包容性索引

  • August 10, 2021

我有四個表,所有表的行數都差不多(客戶除外):

運輸(PackNumber、PackLine、OrderNumber、OrderLine、CustomerID)

訂單(OrderNumber、OrderLine)

發票(PackNumber、PackLine)

客戶(CustID)

我在優化時對 2 個儲存過程執行查詢計劃,一個查詢有這樣的連接

SELECT ...
FROM Shipping s 
   INNER JOIN Orders o ON s.OrderNumber = o.OrderNumber AND s.OrderLine = o.OrderLine
   INNER JOIN Customer c ON s.CustomerID = c.CustomerID

另一個有這樣的連接

SELECT ...
FROM Shipping s
   INNER JOIN Invoices i ON s.PackNumber = i.PackNumber AND s.PackLine = i.PackLine
   INNER JOIN Customer c ON s.CustomerID = c.CustomerID

SQL First 建議分別為儲存過程創建這兩個索引

CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (OrderNumber, OrderLine)
CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (PackNumber, PackLine)

有人可以解釋創建兩個索引與僅創建一個索引的優缺點嗎?

CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (OrderNumber, OrderLine, PackNumber, PackLine)

在這種情況下,創建兩個單獨的索引不太可能是正確的選擇。(最後我會談到一個小角落案例)

有了這兩個索引:

CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (OrderNumber, OrderLine)
CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (PackNumber, PackLine)

兩個索引都將為索引提供在鍵列 ( CustomerID) 上查找的相同能力。這些INCLUDE列對於使索引“覆蓋”很有用(即,防止必須在另一個索引(通常是聚集索引或堆)上進行查找以獲得額外的列以滿足查詢)。請注意,組合列的工作方式不同,因為鍵列會影響排序和進行索引查找的能力——但是包含列的排序沒有這種影響。

將具有相同鍵列的索引和不同的包含列組合起來幾乎總是正確的選擇。我肯定會採用這兩個索引,並將它們組合成您推薦的單個索引。

CREATE INDEX ... ON Shipping (CustomerID) INCLUDE (OrderNumber, OrderLine, PackNumber, PackLine)

有時保持較窄索引有意義的一種情況是當您有意掃描索引時。當您有意/有意地掃描索引時,您通常希望將其縮小。窄索引更小——它們佔用的磁碟空間更少——這意味著您的掃描將佔用更少的 IO,並且完成得更快。將磁碟大小加倍可能會使掃描時間加倍。

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