簡體   English   中英

參數導致SQL Server中的表掃描

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM