Sql-Server

當以前快速的 SQL 查詢開始執行緩慢時,我在哪裡尋找問題的根源?

  • November 5, 2021

背景

我有一個針對 SQL Server 2008 R2 執行的查詢,它連接和/或左連接大約 12 個不同的“表”。該數據庫相當大,有許多超過 5000 萬行的表和大約 300 個不同的表。這是一家在全國擁有 10 個倉庫的大型公司。所有的倉庫都對數據庫進行讀寫。所以它很大而且很忙。

我遇到問題的查詢如下所示:

select t1.something, t2.something, etc.
from Table1 t1
   inner join Table2 t2 on t1.id = t2.t1id
   left outer join (select * from table 3) t3 on t3.t1id = t1.t1id
   [etc]...
where t1.something = 123

請注意,其中一個聯接位於非相關子查詢上。

問題是,從今天早上開始,系統沒有任何更改(我或我團隊中的任何人都知道),通常需要大約 2 分鐘才能執行的查詢開始需要一個半小時​​才能執行 - 當它根本跑了。數據庫的其餘部分執行良好。我已經從它通常執行的儲存過程中取出了這個查詢,並且我已經在帶有硬編碼參數變數的 SSMS 中以同樣的速度執行它。

奇怪的是,當我將不相關的子查詢放入臨時表中,然後使用它而不是子查詢時,查詢執行良好。此外(這對我來說是最奇怪的)如果我將這段程式碼添加到查詢的末尾,查詢執行良好:

and t.name like '%'

我從這些小實驗中得出(可能是錯誤的)結論,減速的原因是由於 SQL 的記憶體執行計劃是如何設置的——當查詢有點不同時,它必須創建一個新的執行計劃。

**我的問題是:**當一個曾經快速執行的查詢突然在半夜開始緩慢執行並且除了這個查詢之外沒有其他任何影響,我該如何解決它以及如何防止它在未來發生? 我怎麼知道 SQL 在內部做了什麼讓它變得這麼慢(如果執行了錯誤的查詢,我可以獲得它的執行計劃但它不會執行——也許預期的執行計劃會給我一些東西?)?如果這個問題與執行計劃有關,我如何讓 SQL 不認為真正糟糕的執行計劃是個好主意?

此外,這不是參數嗅探的問題。我以前見過,但事實並非如此,因為即使我在 SSMS 中對變數進行硬編碼,我的性能仍然很慢。

當一個曾經執行速度很快的查詢在半夜突然開始執行緩慢並且除了這個查詢之外沒有其他任何影響,我該如何解決它……?

您可以首先檢查執行計劃是否仍在記憶體中。檢查和。sys.dm_exec_query_stats_ 如果仍然記憶體了錯誤的執行計劃,您可以對其進行分析,還可以檢查執行統計資訊。執行統計資訊將包含邏輯讀取、CPU 時間和執行時間等資訊。這些可以有力地表明問題所在(例如,大掃描與阻塞)。有關如何解釋數據的說明,請參閱辨識問題查詢。sys.dm_exec_procedure_statssys.dm_exec_cached_plans

此外,這不是參數嗅探的問題。我以前見過,但事實並非如此,因為即使我在 SSMS 中對變數進行硬編碼,我的性能仍然很慢。

我不相信。SSMS 中的硬編碼變數並不能證明過去的錯誤執行計劃不是針對傾斜的輸入進行編譯的。請閱讀Parameter Sniffing, Embedding, and the RECOMPILE Options以獲得關於該主題的非常好的文章。應用程序慢,SSMS 快?了解性能奧秘 是另一個很好的參考。

我從這些小實驗中得出(可能是錯誤的)結論,減速的原因是由於 SQL 的記憶體執行計劃是如何設置的——當查詢有點不同時,它必須創建一個新的執行計劃。

這可以很容易地測試。SET STATISTICS TIME ON將向您顯示編譯與執行時間。SQL Server:Statistics性能計數器也會顯示編譯是否是一個問題(坦率地說,我覺得不太可能)。

但是,您可能會遇到類似的問題:查詢授權門。有關詳細資訊,請閱讀了解 SQL Server 記憶體授予。如果您的查詢在沒有可用記憶體的情況下請求大筆授權,它將不得不等待,並且對於應用程序來說,這一切看起來都是“緩慢執行”。分析等待資訊統計數據將揭示是否是這種情況。

有關要衡量的內容和要查找的內容的更一般性討論,請參閱如何分析 SQL Server 性能

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