小编典典

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

sql

我有一个使用下面列出的代码执行SQL查询的C#程序。我一直在使用此代码一段时间,直到前一天都没有问题。

我正在将一个查询字符串传递给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', '05333210', '05348410', '05361110', '05430310',
    '05493710', '05722410', '05849810', '06050510', '06405810', '06738310',
    '07181310', '07373010', '07588710', '07589610', '08143710', '08467070',
    '08651610', '09062X10', '09247X10', '09367110', '09702310', '09972410')

阅读 200

收藏
2021-05-05

共1个答案

小编典典

按优先顺序看三件事:

  1. 避免使用AddWithValue()function,因为当ADO.Net猜测列类型错误时,这可能会带来灾难性的性能影响。做您必须能够为每个参数设置显式数据库类型的操作
  2. 查看OPTION RECOMPILE。
  3. 研究未知的优化。仅在其他失败之后再执行此操作。
2021-05-05