[英]Parameter cause a table scan in SQL Server
我有兩個表a,b,主鍵是它們的索引。
需求:
如果@filter
為空,則選擇a,b的所有記錄,否則按任何特定分隔符拆分@filter
,查找b.PKey
在過濾器中的記錄。
目前的實施:
declare @filter nvarchar(max)= ''
SELECT *
FROM a
JOIN b ON a.PKey = b.aPKey
AND (@filter = '' OR b.PKey IN (SELECT item FROM splitFunction(@filter))
我發現最后一個語句and (@filter = '' or b.PKey in (select item from splitFunction(@filter))
將始終在表b上進行表掃描,只有當我刪除@filter=''
,它才會改變索引尋求。
有沒有辦法可以實現我的要求並且不會損害性能?
特別針對這種情況,你也可以試試這個:
DECLARE @filter nvarchar(max)= ''
IF @filter = ''
BEGIN
SELECT *
FROM a
JOIN b ON a.PKey = b.aPKey
END
ELSE
BEGIN
SELECT *
FROM a
JOIN b ON a.PKey = b.aPKey
WHERE b.PKey IN (SELECT item FROM splitFunction(@filter))
END
對於常量,優化程序可以根據給定值的統計信息計算出最佳計划。
當您使用變量時,您將強制參數化,並且該計划將被設計為可以重復使用各種值。 所以Optimizer使用掃描而不是搜索。 要解決此問題,請在查詢中停止使用局部變量,並將其用作存儲過程中的參數
create procedure p1
@filter = ''
as
begin
SELECT *
FROM a
JOIN b ON a.PKey = b.aPKey
AND (@filter = '' OR b.PKey IN (SELECT item FROM splitFunction(@filter))
option (recompile)
end
這將為您提供正確的計划,就像我已將本地變量轉換為參數的存儲過程一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.