如何更改查询超时时间

7

针对查询记录数较多的情况,我遇到了超时问题。如何改变查询超时时间?

我尝试过以下方式修改连接超时时间,但是并没有生效:

connection.ConnectionTimeout = 60; // 不起作用(已就绪)

类:

public abstract class RepositoryBase<TEntity> : IRepositoryBase<TEntity>, IDisposable where TEntity : class
{
    protected SqlConnection _connection;
    protected string _connectionString;

    public RepositoryBase(string connectionString)
    {
        _connectionString = connectionString;
        SqlConnection connection = new SqlConnection(connectionString);
        if (connection.State == ConnectionState.Closed)
            connection.ConnectionTimeout = 60; // not working (ready)
            connection.Open();

        _connection = connection;
    }

    public List<T> GetEntitiesByQuery<T>(string Query)
    {
        using (var connection = _connection)
        {
            try
            {
                var entities = connection.Query<T>(Query);
                return entities.ToList();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                connection.Close();
            }
        }
    }
}

你知道查询需要运行多长时间吗? - Andrew
大约需要1分钟,但超时时间为30秒。 - Rodrigo Martins
对于包含大量记录的查询 - 数据库中的记录数量不应成为查询的瓶颈。如果发生这种情况,那么说明其他地方存在问题。在这里所做的增加超时时间会解决您的问题,但是您正在为更大的问题贴上一个肮脏的创可贴。再次查看您的查询,查看执行计划,检查索引等。 - WynDiesel
我正在执行一个简单的查询(SELECT FIELD1,FIELD2,FIELD3 FROM TABLE),但是查询结果返回了300k条记录。当查询超过30秒时,就会超时。 - Rodrigo Martins
为什么使用 entity-framework 标签?看起来你在使用不同的(微型)ORM? - Ivan Stoev
显示剩余2条评论
3个回答

10
您需要设置 CommandTimeout 属性:

等待命令执行的时间(以秒为单位)。默认值为 30 秒。

如何设置取决于所使用的数据访问技术。

对于纯 ADO.NET:

IDbCommand cmd = ...;
cmd.CommandTimeout = 120; // 2 min

对于EF6:

DbContext db = ...;
db.Database.CommandTimeout = 120; // 2 min

看起来你正在使用Dapper。当前使用的Query<T>方法具有以下签名:

public static IEnumerable<T> Query<T>(
    this IDbConnection cnn,
    string sql,
    object param = null,
    IDbTransaction transaction = null,
    bool buffered = true,
    int? commandTimeout = null,
    CommandType? commandType = null
)

正如您所看到的,有许多可选参数,其中一个是您需要的commandTimeout。因此,您可以使用类似以下的内容:

var entities = connection.Query<T>(Query, commandTimeout: 120);

或者您可以设置所有查询的默认超时时间:

SqlMapper.Settings.CommandTimeout = 120; // 2 min

我使用了 "var entities = connection.Query<T>(Query, commandTimeout: 120);"。 - Rodrigo Martins

0

看起来查询花费的时间超过了60秒。请将其设置为0(无限制)并进行检查。

connection.ConnectionTimeout = 0;

最常接受的方法是通过SqlCommand对象的CommandTimeout属性来实现。


我读了相关资料,但是没有从列表中得到返回值。(List<T>) - Rodrigo Martins

0
如果超时是只读的,这意味着您已经连接到数据库,否则您可以更改它。 尝试在连接字符串中设置超时时间,也许可以更好地组织代码。
 <connectionStrings>  
    <... connectionString="User ID=sa;Password=XXXXX;Initial Catalog=qualitaBorri;Data Source=PC_NAME\SQLEXPRESS;Connection Timeout=60"/>
  </connectionStrings>

我已经尝试过这种方式,但是这个超时时间是银行连接时间而不是查询时间。 - Rodrigo Martins
我不确定,但你应该检查服务器端是否在本地运行对 SQLServer 的查询。SQLServer 有自己的超时时间,所以无论你的代码如何,如果服务器认为你的查询时间太长,那么它就是无用的。因此,坚持这个方向是没有意义的,你可能需要考虑不同的方法来获取数据,例如你实际调用了多少行?你能想到一种优化的方法吗?你可以使用存储过程或分页调用吗? - Zwan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接