2011-06-26 51 views
2

因此,我使用一個10年曆史的系統上的.net 3.5 Web前端的大型數據庫(30 gig)sql 2005。它有新舊比特運行存儲過程的隨機超時重新創建修復程序

我們正在越來越頻繁地發生問題。

一個存儲過程(到目前爲止我們有4個不同的過程)決定它會超時。該呼叫發生在網絡服務器上,並觸發30秒超時並記錄到我們的錯誤日誌中。該網站使用單一登錄(我知道這是錯誤的,但由於遺留代碼無法更改)。

就在此之後,我運行完全相同的調用,它需要(以我身份登錄)1秒。

問題仍然存在於這個存儲過程中,直到我們刪除並重新創建它,獲取超時負載。每個sp呼叫具有不同的參數。 因爲在得到所有與當前用戶有關的未簽名關閉轉移時,所以當前用戶作爲參數傳入

該解決方案有效,但我不太明白爲什麼。

我們的發佈週期是兩個星期,而且這個錯誤在任何時候都會發生。它在發佈後一週發佈後的第二天發佈,最後一天是發佈後的第12天。

爲每個發佈的版本添加一個SQL多重腳本,每個腳本都存放procs/triggers/functions/views,每個腳本都會刪除並重新創建。

我能想到的是,存儲的proc執行計劃已經損壞/出錯了,並且刪除重新創建它會清除它。

我想調用sps WITH RECOMPILE選項,這是否是否定的?或者一個可接受的方式

回答

3

這聽起來非常像我一次又一次看到的問題 - 存儲過程計劃已從計劃緩存中刷新,並且下一次運行該過程時,只會發生傳入參數在一個可能對這組參數非常好的計劃中,但是對於其他組合來說,這個計劃表現得非常好。

如果你已經「可選」的參數 - 在NULL 值可以穿過,而你的WHERE子句中使用OR應對這一則通常是怎麼回事導致這樣的事情。

WITH RECOMPILE可能會導致大量CPU去編譯計劃 - 如果存儲過程被調用很多,那麼這可能很容易影響服務器的一般性能 - 無論這個os是否超過一個壞計劃的效果是另一回事。

一般來說,最好嘗試重寫查詢 - 如果您使用的是OR來處理不同的參數集,那麼動態SQL(以正確的方式使用帶參數的sp_executesql)可以提供很多幫助。

P.S.關於存儲過程在運行時工作正常 - 我也看到了這一點 - 我期望能夠生成一個不同的計劃 - 我的懷疑一直是通過例如運行的。 SSMS與(在我的例子中).Net相比,啓用了一些SET選項稍有不同,並且計劃在這種情況下分開緩存。如果任何人都可以驗證這可能會發生它將不勝感激!

0

我懷疑它是直接導致這種情況的存儲過程,除非它正在執行某種不被清理的鎖定/事務邏輯。即使如此,我也不知道如何放棄/重新創建會對此產生任何影響。我可能會查看SP正在使用的數據,並嘗試跟蹤此分析的執行路徑,並查看性能是否可以提高。

+0

「我看不出如何丟棄/重新創建會對此產生任何影響」。如果性能問題是鎖定/事務邏輯,它將不會產生任何影響,但如果問題與執行計劃相關,則會產生巨大影響。重新創建SP(ALTER或DROP/CREATE)將刷新當前的執行計劃,強制在下一次調用時生成新的執行計劃。這可以產生巨大的差異。 –

0

這很可能是由於針對特定proc存儲的錯誤執行計劃造成的。

問題(簡化)是SQL Server嘗試根據傳遞的參數優化執行計劃的使用。這在某些情況下會導致可怕的表現。

繼承人一些閱讀進一步解釋。

http://blogs.msdn.com/b/queryoptteam/archive/2006/03/31/565991.aspx
http://elegantcode.com/2008/05/17/sql-parameter-sniffing-and-what-to-do-about-it/

在光明的一面,它很簡單的通過在proc局部變量拷貝傳遞的參數來解決。