sql - 在一个表上的简单选择查询中获取消息 8623,级别 16,状态 1,第 1 行错误

标签 sql sql-server tsql subquery sql-in

如何优化在一个表上搜索不属于集合的 ID 的简单查询。

我创建了以下查询

Select userId 
from user 
where userId not in (5000, 5001, 5002, 5003, more....)

请注意,该列表包括 35000 多行。我收到以下数据库错误

Msg 8623, Level 16, State 1, Line 1
The query processor ran out of internal resources and could not produce a query plan. This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions.

有些人建议使用左连接优化查询,但我只是在一个表中搜索,那么有什么替代方法呢?

最佳答案

这是一个 documented behavior :

Explicitly including an extremely large number of values (many thousands of values separated by commas) within the parentheses, in an IN clause can consume resources and return errors 8623 or 8632. To work around this problem, store the items in the IN list in a table, and use a SELECT subquery within an IN clause.

35000 显然是 数千。因此,根据文档,您应该创建一个表(或临时表)来存储您的值,然后按如下方式左连接:

select u.userId 
from user u
left join mytemptable t on t.userId = u.userId
where t.userId  is null

你也可以使用not exists:

select u.userId
from user u
where not exists (select 1 from mytemptable t where t.userId = u.userId)

作为奖励,请注意使用上述技术之一修复了原始查询的空安全问题(实际上,如果 IN 列表中的任何值是 NULLNOT IN 条件将被视为满足,无论 userId 的值如何。

关于sql - 在一个表上的简单选择查询中获取消息 8623,级别 16,状态 1,第 1 行错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59922572/

相关文章:

c# - 运行存储过程时的 Entity Framework 问题

sql - 如何在 WHERE 子句中引用别名?

sql - 查找表有多重要?

php - 从 HTMl 表单的动态选择选项中删除重复数据

mysql - 如何在 SQL 查询的 WHERE 子句中使用表值?

mysql - 编写 SQL 查询以打印表中不包含 '%' 符号的单词

sql-server - 微软 SQL : Update only if data record does not exist

c# - Visual Studio/Microsoft sql 关系键错误

sql-server - 复合增量列

sql-server - T-SQL 按特定顺序添加列