从C#运行时SQL查询超时,在SQL Server Management Studio中快速

fre*_*les 11 c# sql sql-server ado.net sql-server-2008

我有一个C#程序,使用下面列出的代码执行SQL查询.我已经使用这段代码一段时间没有问题直到前几天.

我将查询字符串传递给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();
}
Run Code Online (Sandbox Code Playgroud)

这是我的查询.在这个版本中,我包括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')
Run Code Online (Sandbox Code Playgroud)

Joe*_*orn 8

根据偏好顺序要看三件事:

  1. 避免使用该AddWithValue()函数,因为当ADO.Net猜错列类型时,可能会产生灾难性的性能影响.执行必须为每个参数设置显式DB类型的操作
  2. 查看OPTION RECOMPILE.
  3. 查看OPTIMIZE FOR UNKNOWN.只有在其他人失败后才这样做.