2015-03-31 106 views
8

我有一個C#程序,它使用下面列出的代碼執行SQL查詢。直到有一天,我一直在使用這段代碼一段時間沒有問題。SQL查詢超時從C#運行,在SQL Server Management Studio中快速運行

我將查詢字符串傳遞給SQL,其中包含字符串(庫存標識符)列表。前幾天我跑了它,查詢超時了,如果我讓它跑了一個多小時。我花了幾天試圖調試這個。在我原來的查詢中,大約有900個標識符。

我試過改變一切我能想到的,我得到的結果我無法解釋。

例如:

  1. 的查詢工作與股票的一個列表,但不與相同長度的另一個列表中的字符串,總長度的數量方面

  2. 它與一個列表但不包含相同的列表以相反的順序

  3. 帶有一個列表,它的工作原理是,如果確切地有900個標識符,但沒有899或901,我可以包含或排除不同的標識符並獲得相同的結果,所以對於其中一個標識符來說這不是一件怪事。

在每一種情況下,我捕捉到正由我的程序通過,並複製到SQL Server Management Studio中的查詢字符串,並且在任何情況下,查詢在1秒內​​運行。

我已經閱讀了本文以及其他論壇上關於在SQL Server Management Studio中工作的查詢的所有內容,但是從程序運行時超時,但這看起來不同,因爲我可以找到它失敗的情況以及類似的情況它不起作用。

我希望能夠看到可能發生的事情的建議。

using (SqlConnection conn = new SqlConnection(_connectString)) 
{ 
    conn.Open(); 

    using (SqlCommand cmd = new SqlCommand(queryString, conn)) 
    { 
     cmd.Parameters.Clear(); 
     cmd.CommandTimeout = _timeout; 

     SqlParameter param; 

     if (parms != null) 
     { 
      foreach (string parm in parms.Keys) 
      { 
       param = cmd.Parameters.AddWithValue(parm, parms[parm]); 
      } 
     } 

     SqlDataReader reader = cmd.ExecuteReader(); 

     while (reader.Read()) 
     { 
      QueryResult record = new QueryResult(); 
      record.Fields = new List<object>(); 

      for (int i = 0; i < returnColumns; ++i) 
      { 
       object value = reader.GetValue(i); 

       if (value == DBNull.Value) 
        record.Fields.Add(null); 
       else 
        record.Fields.Add(value); 
      } 

      result.Add(record); 
     } 

     reader.Close(); 
    } 

    conn.Close(); 
} 

這是我的查詢。在這個版本中,我包括65個股票,它不起作用(< = 64確實有效)。

select 
    distinct a.Cusip 
, d.Value_/f.CumAdjFactor as split_adj_val 

from qai.prc.PrcScChg a 

join qai.dbo.SecMapX b 
    on a.Code = b.venCode 
    and b.VenType = 1 
    and b.exchange = 1 
    and b.Rank = (select Min(Rank) from qai.dbo.SecMapX where VenCode = a.Code and VenType = 1 and Exchange = 1) 

join qai.dbo.SecMapX b2 
    on b2.seccode = b.seccode 
    and b2.ventype = 40 
    and b2.exchange = 1 
    and b2.Rank = (select Min(Rank) from qai.dbo.SecMapX where SecCode = b.SecCode and VenType = 40 and Exchange = 1) 

join qai.dbo.SecMapX b3 
    on b3.seccode = b.seccode 
    and b3.ventype = 33 
    and b3.exchange = 1 
    and b3.Rank = (select Min(Rank) from qai.dbo.SecMapX where SecCode = b.SecCode and VenType = 33 and Exchange = 1) 

join qai.dbo.DXLSecInfo c 
    on b2.VenCode = c.Code 

join qai.dbo.DXLAmData d 
    on c.Code = d.Code 
    and d.Date_ = @Date 
    and d.Item = 6 

left JOIN qai.dbo.DS2Adj f 
    ON f.InfoCode = b3.VenCode 
    AND f.AdjType = 2 
    and f.AdjDate <= @Date 
    and (f.EndAdjDate >= @Date or f.EndAdjDate is null) 

where 
    a.cusip in ('00101J10', '00105510', '00120410', '00130H10', '00206R10', 
    '00282410', '00287Y10', '00289620', '00724F10', '00817Y10', '00846U10', 
    '00915810', '00936310', '00971T10', '01381710', '01535110', '01741R10', 
    '01849010', '02000210', '02144110', '02209S10', '02313510', '02360810', 
    '02553710', '02581610', '02687478', '03027X10', '03073E10', '03076C10', 
    '03110010', '03116210', '03209510', '03251110', '03265410', '03741110', 
    '03748R10', '03783310', '03822210', '03948310', '04621X10', '05276910', 
    '05301510', '05329W10', '', '05348410', '05361110', '05430310', 
    '05493710', '05722410', '05849810', '06050510', '06405810', '06738310', 
    '07181310', '07373010', '07588710', '07589610', '08143710', '08467070', 
    '08651610', '09062X10', '09247X10', '09367110', '09702310', '09972410') 
+2

我們需要一個查詢字符串的例子嗎?可以是很多事情,可能需要索引,查詢重寫等等。 – ibiza 2015-03-31 18:36:58

+0

您需要指定連接字符串中的超時時間(足夠長以完成查詢) – 2015-03-31 18:37:17

+0

_timeout的值是什麼? – UnhandledExcepSean 2015-03-31 18:39:18

回答

6

三件事情來看待,按優先順序:

  1. Avoid using the AddWithValue() function,因爲這可以帶來災難性的性能影響時ADO.Net猜測列類型錯誤。做你必須能夠爲每個參數設置一個明確的DB類型
  2. 看看OPTION RECOMPILE
  3. 調查OPTIMIZE FOR UNKNOWN。只有在其他人失敗後才能做到這一點。
+0

謝謝,我會試試這些。我也發現週四晚上有一些Windows更新應用到了服務器上(週五我開始有問題),所以我們的IT人員正在研究這些問題。 – freckles 2015-04-01 19:52:46

+0

添加而不是AddWithValue沒有幫助(雖然我做了這個改變)。並感謝鏈接到未知信息的優化,這是非常有用的。我添加了這個選項,它絕對解決了這個問題。謝謝! – freckles 2015-04-01 20:57:18

1

您還沒有發佈您的查詢,但只是基於它是如何被使用的參數的動態列表和參數的數量之多,建,我打算做一個猜測,說有事不帶參數的嗅探 - 見:

http://www.brentozar.com/archive/2013/06/the-elephant-and-the-mouse-or-parameter-sniffing-in-sql-server/

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature.aspx

問題的基本思想是一組特定的參數,這是非常次優創建一個最佳的查詢執行計劃換另一套。

有幾種方法可以解決參數嗅探問題(幸運的是,其中許多方法在sql server 2008中打開)。

,你可以:

  1. 重構查詢
  2. 添加WITH RECOMPILE到您的存儲過程/ option (recompile)到您的查詢
  3. optimize for unknown/option (optimize for...您PROC /查詢
  4. 別人呢?
+1

此外,您可以嘗試使用'SET SHOWPLAN_ALL ON查看您的執行計劃; '在測試模式下開始查詢。在工作查詢和非工作查詢中以這種方式運行它,看看是否有明顯的差異(這種格式有點醜陋,因爲它返回的信息表必須經過,與查詢管理器不同,但它可以用來找出不一致的地方) – DarrenMB 2015-03-31 18:48:02

相關問題