排除错误外,基本就是查询语句确实消耗了过多的资源
这次遇到这个错误是因为在 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://*.com/questions/16360236/ef-query-where-list-contains-a-lot-of-elements