Sql-Server

儲存過程中的局部變數

  • December 9, 2021

我在網上讀到,如果您在儲存過程中使用局部變數而不是輸入變數,那麼儲存過程將被優化,就好像它使用提示 OPTIMIZE FOR UNKNOWN 一樣。這到底是怎麼發生的?另外,一般來說,一個好的做法是:直接使用輸入變數或創建局部變數並將輸入變數分配給它們?

發表它

來自我的部落格文章又一篇關於局部變數的文章

在儲存過程中(甚至在即席查詢或動態 SQL 中,如上面連結的範例中),如果您在該程式碼塊中聲明一個變數並稍後將其用作謂詞,您將得到一個固定的基數猜測,或者比使用直方圖時更不可靠的估計。

本文其餘部分討論的局部變數效果產生與 OPTIMIZE FOR UNKNOWN 提示或使用 sp_prepare 執行查詢相同的行為。

對於單個相等謂詞,該估計將基於表中的行數和列的“所有密度”相乘。多個謂詞的過程取決於您使用的基數估計模型。

你得到的猜測取決於你使用什麼樣的謂詞。

相等謂詞將表基數乘以列選擇性:

堅果

並且不等式謂詞使用不同的固定百分比的表基數,具體取決於您使用的基數估計模型。

堅果

正如現有評論中提到的,這通常是由於在決定使用什麼記憶體計劃或何時生成新計劃時進行參數嗅探。這通常是“應用程序慢,SSMS 快”問題的原因(並不總是原因,這不是唯一的症狀)。

Erland Sommarskog 有一個很好的詳細但可讀的問題概述,當他發現(或人們報告)新的不同邊緣情況時會更新,在https://www.sommarskog.se/query-plan-mysteries.html

他包括其他可能的原因、潛在的修復方法以及它們何時可能/無用。youtube 上還有幾個影片,是關於他在會議和其他活動中談論這個主題的(儘管寬度和深度不同),如果您以這種方式更好地理解/保留新資訊,您可能希望找到這些影片。

在使用技巧來強制執行多個計劃以避免嗅探問題時要小心的一件事是,在某些情況下,您最終可能會用大量執行相同的範例來填充計劃記憶體,從而導致更少的空間來記憶體其他部分的更有用的計劃您的應用程序。您還可能給自己帶來新的性能問題,因為每次編譯計劃都比使用不太優化的儲存計劃浪費更多時間。因此,不要試圖通過嘗試解釋尚未明顯的參數嗅探問題的可能性來過早優化,只需在診斷符合這些模式的未來性能問題時牢記這個概念。

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