Min*_*dan 3 sql t-sql sql-server subquery sql-in
如何优化在一个表中搜索不属于一组的 ID 的简单查询。
我创建了以下查询
Select userId
from user
where userId not in (5000, 5001, 5002, 5003, more....)
Run Code Online (Sandbox Code Playgroud)
请注意,该列表包含超过 35000 行。我收到以下数据库错误
消息 8623,级别 16,状态 1,第 1 行
查询处理器耗尽内部资源,无法生成查询计划。这是一种罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。
有些人建议通过使用左连接来优化查询,但我只是在一个表中搜索,那么还有什么选择呢?
这是有记录的行为:
在子句中的括号内显式包含大量值(用逗号分隔的数千个值)
IN可能会消耗资源并返回错误 8623 或 8632。要解决此问题,请将列表中的项目存储在IN表中,并在子句SELECT中使用子查询IN。
35000 显然符合数千人的资格。因此,根据文档,您应该创建一个表(或临时表)来存储您的值,然后left join如下所示:
select u.userId
from user u
left join mytemptable t on t.userId = u.userId
where t.userId is null
Run Code Online (Sandbox Code Playgroud)
您还可以使用not exists:
select u.userId
from user u
where not exists (select 1 from mytemptable t where t.userId = u.userId)
Run Code Online (Sandbox Code Playgroud)
作为奖励,请注意,使用上述技术之一可以修复原始查询的空安全问题(事实上,如果列表中的任何值是 ,则无论 的值IN如何NULL,NOT IN条件都将被视为满足userId) 。