我的SQL Server 2016上和我看到以下內容:SQL常數函數導致使用劣質查詢計劃
我有類似簡單的查詢:
select distinct col1
from tbl
where
col2 > 12345
如果我移動不變值成一個函數,查詢計劃的變化(惡化,由A LOT):
select distinct col1
from tbl
where
col2 > dbo.fn12345()
其中函數是
create function dbo.fn12345()
returns int
as begin
return 12345
end
這裏是計劃的屏幕截圖(使用我的實際模式,因此標識符與說明性示例不同。
隨着第二計劃執行我的時間的推移,從22秒到96S。
有沒有辦法解決這個問題,同時仍然使用函數?
請不要問我爲什麼不能內聯恆定。對於更復雜的函數也會出現同樣的問題,這些函數包括可控邏輯 - 內聯什麼是有效的複雜常數計算會改變查詢計劃。
我也知道我的索引不是最優的。這是設計。該表非常大,並且此特定查詢不保證專用索引的存儲空間。
標量UDF在where子句中出現問題。有趣的是,我不能在dbfiddle上覆制。在那裏它被評估一次並用於尋找。也許這是一個已經改進的領域。什麼是你的@@版本? http://dbfiddle.uk/?rdbms=sqlserver_2016&fiddle=7056d010e684b76f727bd4f38c433196 –
Microsoft SQL Server 2016(SP1-CU2)(KB4013106) - 13.0.4422.0(X64) – CoderBrien
由於數據和表格的原因,您可能會有一段艱難的時間。我認爲300MM行。另外我使用選項(使用提示('DISABLE_OPTIMIZED_NESTED_LOOP'))作爲加速。沒有提示它會進行排序並泄漏到tempdb。 – CoderBrien