Sql-Server

列包含的原因

  • January 11, 2022

我們有一個簡單的查詢:

SELECT COUNT(1) 
 FROM E 
WHERE E_CUS_ID = CUS_ID 
  AND E_DATE_OPENED IS NOT NULL 
  AND E_DATE_OPENED < DATEADD(DAY, 7, E_DATE_SENT)

SQL Server SSMS建議以下索引:

CREATE NONCLUSTERED INDEX IX_EMAIL_4
   ON [dbo].[EMAIL] ([E_CUS_ID],[E_DATE_OPENED])
INCLUDE ([E_DATE_SENT])

為了以最佳方式覆蓋,我會假設它將E_DATE_SENT作為關鍵列包含在內,因為它位於WHERE子句中。

請問 SQL Server 可能使用哪些原因來決定該列應該是 Key 還是 Included 列?

我希望自己學習如何在列放置方面做出更好的選擇。

有點奇怪的是,如果我將此查詢修改為:

SELECT COUNT(1) 
 FROM E 
WHERE E_CUS_ID = 1912 
  AND E_DATE_OPENED < DATEADD(DAY, 7, E_DATE_SENT)

我假設它會產生相同的輸出,因為 NULL 日期在下一個條件下永遠不會評估為真,SSMS 將其建議更改為:

CREATE NONCLUSTERED INDEX IX_EMAIL_4
   ON [dbo].[EMAIL] ([E_CUS_ID])
INCLUDE ([E_DATE_SENT],[E_DATE_OPENED])

在性能改進期間,無論如何我都打算IS NOT NULL從查詢中刪除這個子句,那麼我應該創建哪個索引?為什麼?

首先:缺少索引請求並不聰明。完全沒有。說得客氣一點。我喜歡認為它沒有很多 CPU 週期來生成建議。

但是,在這種情況下,建議是有邏輯的。考慮這個謂詞:

E_DATE_OPENED < DATEADD(DAY, 7, E_DATE_SENT)

無法為其查找索引,因為您基本上是比較兩個不同列之間的值。

E_DATE_OPENED 在第一個範例的關鍵中的原因是它包含以下謂詞:

E_DATE_OPENED 不為空

對於上述情況,絕對可以搜尋索引;因此,在鍵中包含該列是有意義的。

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