我有一个C#程序,使用下面列出的代码执行SQL查询.我已经使用这段代码一段时间没有问题,直到前几天.
我将查询字符串传递给sql,其中包含一个字符串列表,这些字符串是库存标识符.几天前我运行它,查询超时,如果我让它运行一个多小时.我花了这么多天试图调试这个.在我的原始查询中,大约有900个标识符.
我已经尝试过改变我能想到的一切,但我得到了无法解释的结果.
例如:
>查询使用一个股票列表,但不能使用另一个字符串和总长度相同的长度列表
>它适用于一个列表但不能以相反的顺序使用相同的列表
>有一个列表,如果有正好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','05333210','05348410','05361110','05430310','05493710','05722410','05849810','06050510','06405810','06738310','07181310','07373010','07588710','07589610','08143710','08467070','08651610','09062X10','09247X10','09367110','09702310','09972410')
解决方法
根据偏好顺序要看三件事:
> Avoid using the AddWithValue()
function,因为当ADO.Net猜测列类型错误时,可能会产生灾难性的性能影响.执行必须为每个参数设置显式DB类型的操作
>看看OPTION RECOMPILE.
>查看OPTIMIZE FOR UNKNOWN.仅在其他人失败后才这样做.