数据库
首页 > 数据库> > SQL SERVER 错误:查询处理器用尽了内部资源,无法生成查询计划。这种情况很少出现,只有在查询极其复杂或引用了大量表或分区时才会出现。请简化查询。如果您认为该消息的出现纯属错误,请与客户支持服务

SQL SERVER 错误:查询处理器用尽了内部资源,无法生成查询计划。这种情况很少出现,只有在查询极其复杂或引用了大量表或分区时才会出现。请简化查询。如果您认为该消息的出现纯属错误,请与客户支持服务

作者:互联网

排除错误外,基本就是查询语句确实消耗了过多的资源

这次遇到这个错误是因为在 where 语句中 in 了过多的数据(大概 10000+)

需要调整一下查询逻辑了

根据不同的业务逻辑可能有不同的调整方式,这里介绍一个用了感觉还比较有效的方法

就是在查询过程中将需要 in 查询的所有数据插入临时表,然后通过 join 临时表或子查询的方式来达到同样的效果

如果是用 ef + linq 查询的话,可能需要在数据库中创建一个固定的临时表,通过构建一个查询批次 id 来应对并发

CREATE TABLE [dbo].[temp_table](
    [QueryId] [uniqueidentifier] NOT NULL,
    [DataId] [bigint] NOT NULL
)

在代码中,通过批量插入来提高效率

private static Guid SetTempTable(IEnumerable<long> dataIds)
{
    var temp_table = new DataTable("temp_table");
    temp_table.Columns.Add("QueryId", typeof(Guid));
    temp_table.Columns.Add("DataId", typeof(long));
    var queryId = Guid.NewGuid();
    foreach (var recordId in dataIds)
    {
        temp_table.Rows.Add(queryId, recordId);
    }

    SqlHelper.BulkCopyDataTable(temp_table, temp_table.TableName);

    return queryId;
}

使用 join 查询

var query = from user in user_table join id in temp_table on user.UserId equals id.DataId select user

使用完成后直接批量删除

private static void ClearTempTable(Guid queryId)
{
    SqlHelper.ExecuteNonQuery("DELETE FROM temp_table WHERE QueryId = @QueryId", new SqlParameter("@QueryId", queryId));
}

除了对已经查不出来的 in 条件外,对能查出来的查询速度提升也很明显~

参考:https://stackoverflow.com/questions/16360236/ef-query-where-list-contains-a-lot-of-elements

标签:错误,temp,时才,查询,QueryId,queryId,table,Guid
来源: https://www.cnblogs.com/xwgli/p/13894518.html