2016-08-23 102 views
0

所以這是場景:sp_execute選擇不同的查詢計劃

表中有許多字段。 Field2是聚簇索引中唯一的字段。 存在不包含任何其他字段的Field1,Field2唯一索引。

表中有500000行,其中499900個字段爲空值。

查詢1:

SELECT TOP (1) * 
FROM Table WITH(UPDLOCK) 
WHERE (Field1='XXX') ORDER BY Field1 DESC, Field2 DESC OPTION(OPTIMIZE FOR UNKNOWN) 

可生產索引查找唯一索引字段1,字段2,然後鍵查找到聚集索引,並且是非常快的。

然而,

Declare @P1 int; 
Exec sp_prepare @P1 output, 
N'@0 nvarchar(20)', 
N'SELECT TOP (1) * 
FROM Table WITH(UPDLOCK) 
WHERE ([email protected]) ORDER BY Field1 DESC, Field2 DESC OPTION(OPTIMIZE FOR UNKNOWN)'; 
Exec sp_execute @P1, N'XXX' 
EXEC sp_unprepare @P1; 

產生一個簇索引掃描,這是緩慢的。

DBCC FREEPROCCACHE沒有幫助,所以它不是問題與兌現查詢計劃。

問題是,爲什麼區別?

謝謝。

編輯:意外地將同樣的事情放入第二個查詢中,更新以正確反映它。

+0

我想知道如果將@ P1參數硬編碼到命令字符串中會發生什麼情況。那麼執行時間是多少? – PacoDePaco

+0

對參數進行硬編碼使計劃保持一致。 – mrQQ

回答

0

這是由於參數是可變的,如果你硬編碼它將返回到相同的計劃,或者如果你把參數放在正常執行中,它將生成計劃來掃描。

+0

很明顯,這是唯一的區別,但爲什麼?這在哪裏記錄? – mrQQ

+0

您可以在[this](https://msdn.microsoft.com/en-us/library/ee343986(SQL.100).aspx)文章中獲得一些信息。在我看來,Itzik Ben-Gan'查詢Microsoft SQL Server 2012'第17章第2課:'使用參數化查詢和批處理操作'的書很好地解釋了它。 – PacoDePaco

+0

您認爲文章的哪一部分與此有關? – mrQQ