Sql-Server

使用 FORCESEEK 時收到“由於此查詢中定義的提示,查詢處理器無法生成查詢計劃”但可以使用 FORCESCAN?

  • July 16, 2020

我有一個相當大的表(5 億行,30 列寬,總共大約 130 GB 的數據)。該表中的一列是 DateTime 數據類型,我需要在某個日期範圍內重複從該表中選擇記錄。對我來說似乎是過濾索引的好候選人。

這是我的過濾索引:

CREATE NONCLUSTERED INDEX IX_Filtered_Table1_DateField1 
ON Table1 (DateField1, PrimaryKeyField) 
WHERE (DateField1 >= '2/24/20' AND DateField1 < '4/14/20')

這是我的查詢:

DECLARE @MinPrimaryKeyId BIGINT = 2854868995

SELECT TOP 500000 PrimaryKeyField
INTO #Results
FROM Table1 WITH(INDEX(IX_Filtered_Table1_DateField1))
WHERE DateField1 >= '2/24/20'
and DateField1 < '4/14/20'
and PrimaryKeyField > @MinPrimaryKeyId
ORDER BY PrimaryKeyField ASC

在檢查執行計劃時,我注意到它使用的是我的過濾索引,但它預設為索引掃描操作而不是索引搜尋。

如果我嘗試使用 FORCESEEK 查詢提示(除了我的索引提示),我會收到經典錯誤:

由於此查詢中定義的提示,查詢處理器無法生成查詢計劃

為什麼查詢處理器無法在該索引上使用 Seek 操作生成執行計劃,但它可以使用它執行 Scan 操作?(如果我用 FORCESCAN 切換我的 FORCESEEK 查詢提示,它就可以工作,我知道這與在這裡根本不使用提示沒有什麼不同。)

SQL 無法“搜尋”,因為此索引的順序是先按日期,然後按 PrimaryKey。由於您選擇的日期與索引的全部內容相匹配,並且 PrimaryKey 沒有排序(它們是但僅在每個特定日期內),因此 SQL 必須對其進行掃描。

嘗試為此更改索引:

CREATE NONCLUSTERED INDEX IX_Filtered_Table1_PrimaryKeyField
ON Table1 (PrimaryKeyField) 
WHERE (DateField1 >= '2/24/20' AND DateField1 < '4/14/20')

然後 Sql 應該能夠使用它(作為日期匹配)並尋找 PrimaryKeyField (並且可能不需要提示,因為這可能是 SQL 無論如何都會決定做的)

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