2016-02-24 49 views
0

這是我的問題。我正在使用SQL Server 2014.我有一個ASP.Net Web應用程序,它接受來自用戶的字符串。該字符串被傳遞給存儲過程(SP),該存儲過程查詢查詢鏈接服務器的視圖。我的數據訪問層向我的業務對象返回一個數據表。如果有數據 - 輸入的字符串被認爲是有效的(它在鏈接的服務器上有匹配)。如果沒有數據,輸入的字符串被認爲是無效的(鏈接服務器上沒有匹配)。需要定期刪除並重新創建存儲過程?

那麼簡單,這裏是信息的路徑:

Web應用程序 - 存儲過程 - 視圖 - 鏈接服務器 - 表數據

顯然,這條道路是相反的,一旦執行查詢(和數據傳遞從表格並最終到網絡應用程序)。

這裏是它變得奇怪。自創建SP(今天是第二次)以來,在過去13個月中曾兩次沒有數據在VALID字符串輸入時返回到Web應用程序。要清楚的是,這個SP總是有效(除了這兩次)。但是,一旦失敗,它就不會運行,直到它被丟棄並重新創建。

所以,這裏是什麼工作:

  • 查詢鏈接服務器,直接,並添加字符串到 WHERE子句。
  • 直接查詢視圖,並將字符串添加到WHERE 子句中。

這裏是行不通:

  • 輸入串入網絡的應用程序。
  • 直接查詢SP,並將字符串作爲參數傳遞。

而且真的,真的很怪異的一部分:

兩次出現這種情況,刪除並重新創建存儲過程解決了這個問題。 SP如何運行數月,然後停止工作?那麼如何解決這個問題呢就是放棄並重新創建SP?

首先,這是爲什麼發生?還有很多其他的Web應用程序調用SP,它們調用視圖,調用從未失敗的SAME鏈接服務器。但一年兩次ONE SP失敗沒有明顯的原因 - 刪除並重新創建它解決了這個問題?

請幫忙 - 這真是令人困惑......請讓我知道你是否需要更多信息。

編輯

針對alroc的評論:

  • 創建存儲過程並沒有什麼 做安全的腳本。任何可以訪問數據庫的用戶都可以訪問SP。
  • 我是這裏唯一的DBA,所以沒有其他人「應該」更改DB上的任何 安全或權限。但是,如果他們在做 ,那麼我會在其他地方預期這些問題,因爲網絡應用程序 使用相同的SQL登錄(相同的連接字符串),適用於每個其他進程的 - 並且有數百個。

第二個編輯

針對beercohol的評論:

  • 查詢不超時 - 它不返回任何結果幾乎瞬間。 超時設置爲30秒,接近 的閾值接近此閾值。
  • 我運行了DBCC CheckDB,沒有發現錯誤。
  • 我會在下次發生這種情況時嘗試重新編譯SP,但爲什麼執行計劃會定期對數百或數千個SP中的某個SP執行失敗?
+0

創建SP的腳本是否也授予與其相關的任何安全性?如果是這樣,是否有人可能會「修復」安全性,並在這個過程中撤銷你的SP所依賴的東西? – alroc

+0

@alroc我編輯了我的答案以迴應您的評論。 –

+0

我會檢查兩件事 - 1)你確定查詢在返回「無數據」時沒有超時? 2)運行DBCC CHECKDB檢查數據庫是否損壞。 – beercohol

回答

0

此問題已解決。添加WITH RECOMPILE已永久解決該問題。我和另一位軟件開發人員交談過,他告訴我,SQL內部存在一個錯誤,導致緩存的性能計劃隨着時間的推移開始表現越來越差。它仍然沒有解釋爲什麼這隻會發生在一些存儲過程,而不是所有的 - 但是,無論如何,迫使它們在執行後重新編譯工作!

然而,這對於一個高度要求的SP來說不是一個可行的選擇,因爲你不想重新編譯一次巨大的代碼 - 但對我的目的來說,它工作得很好。

1

我還沒有經歷過您描述的確切場景,但我已經處理了一個存儲過程偶爾會開始以極慢的速度運行的實例,儘管基礎數據的變化不大。問題原來是SQL Server的一個稱爲「參數嗅探」的功能。此功能使用在編譯過程時傳遞的參數來確定爲將來調用而緩存的執行計劃。

如果向過程傳遞不同的參數可能會顯着影響生成的執行計劃,則參數嗅探會產生不良影響。你會經常用'搜索'程序來找到這個程序,它需要大量的參數,其中只有少數參數用於任何給定的調用。

在我的情況下,解決方案是通過爲每個參數聲明局部變量並複製值來禁用參數嗅探功能。然後使用局部變量代替該過程的其餘部分的參數。這足以防止優化器在確定執行計劃時使用原始參數值。

+0

是的,我知道參數嗅探,並在過去聽說過類似的問題。我很感謝你的迴應,但這絕對不是問題。該SP有一個參數 - 並且該值絕不影響執行計劃或性能,因爲鏈接的服務器不在該列上編制索引。 –

+1

同意 - 聽起來不像這是你的問題。我沒有任何其他建議,但我會在這裏保留這個答案,以防萬一任何人在頁面上遇到與相關問題發生衝突。 – Stefan