SQL查询超时从C#运行,在SQL Server Management Studio中快速运行
我有一个C#程序,它使用下面列出的代码执行SQL查询。直到有一天,我一直在使用这段代码一段时间没有问题。SQL查询超时从C#运行,在SQL Server Management Studio中快速运行
我将查询字符串传递给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', '', '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。只有在其他人失败后才能做到这一点。
您还没有发布您的查询,但只是基于它是如何被使用的参数的动态列表和参数的数量之多,建,我打算做一个猜测,说有事不带参数的嗅探 - 见:
问题的基本思想是一组特定的参数,这是非常次优创建一个最佳的查询执行计划换另一套。
有几种方法可以解决参数嗅探问题(幸运的是,其中许多方法在sql server 2008中打开)。
,你可以:
- 重构查询
- 添加
WITH RECOMPILE
到您的存储过程/option (recompile)
到您的查询 -
optimize for unknown
/option (optimize for...
您PROC /查询 - 别人呢?
此外,您可以尝试使用'SET SHOWPLAN_ALL ON查看您的执行计划; '在测试模式下开始查询。在工作查询和非工作查询中以这种方式运行它,看看是否有明显的差异(这种格式有点丑陋,因为它返回的信息表必须经过,与查询管理器不同,但它可以用来找出不一致的地方) – DarrenMB 2015-03-31 18:48:02
我们需要一个查询字符串的例子吗?可以是很多事情,可能需要索引,查询重写等等。 – ibiza 2015-03-31 18:36:58
您需要指定连接字符串中的超时时间(足够长以完成查询) – 2015-03-31 18:37:17
_timeout的值是什么? – UnhandledExcepSean 2015-03-31 18:39:18