【问题标题】:Getting Msg 8623, Level 16, State 1, Line 1 error on a simple select query on one table在一个表上的简单选择查询中获取 Msg 8623, Level 16, State 1, Line 1 错误
【发布时间】:2020-05-12 07:45:25
【问题描述】:

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

我创建了以下查询

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

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

消息 8623,第 16 级,状态 1,第 1 行
查询处理器用尽了内部资源,无法生成查询计划。这是一种罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。

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

【问题讨论】:

    标签: sql sql-server tsql subquery sql-in


    【解决方案1】:

    这是documented behavior

    IN 子句中在括号内显式包含大量值(以逗号分隔的数千个值)会消耗资源并返回错误 8623 或 8632。要解决此问题,请将项目存储在表中的IN 列表,并在IN 子句中使用SELECT 子查询。

    35000 显然符合 数千。因此,根据文档,您应该创建一个表(或临时表)来存储您的值,然后 left join 它如下:

    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 的值如何,条件都将被视为已满足。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多