“In”子句可以处理的项目的最大限制

Posted

技术标签:

【中文标题】“In”子句可以处理的项目的最大限制【英文标题】:the maximum limit of items a 'In' clause can handle 【发布时间】:2019-05-30 13:29:22 【问题描述】:

我可以通过编程语言(如 php)传递给数据库的数据有哪些限制。 假设我的数据库中有 100 万条记录,并且我手中有 100 万条数据,我想要进行存在检查。如果我使用类似的查询

 select id from table where id in (array of 1 million data)

会发生什么?这个请求甚至会到达数据库吗? 如果达到,有什么可能性,它返回数据的速度是否会比数据库搜索 id 的一百万个查询或具有数百万个 for 循环的完整选择数据调用更快。

只是为了好奇!

【问题讨论】:

我们使用 .net 做类似的事情,我们将值批量插入到临时表中,然后执行 ....IN (SELECT ID FROM tab...) 虽然不超过 100 万,但它仍然可以正常工作 【参考方案1】:

没有具体的数字,但是,文档指定一旦您拥有“数千”个值,您可能会遇到问题。 IN (Transact-SQL) - Remarks:

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

错误 8623:

查询处理器用尽了内部资源,无法生成查询计划。这是一个罕见的事件,只预计 极其复杂的查询或引用非常大的查询 表或分区的数量。请简化查询。如果你 相信您错误地收到了此消息,请联系客户 支持服务了解更多信息。

错误 8632:

内部错误:已达到表达式服务限制。请在您的查询中寻找可能复杂的表达式,然后尝试 简化它们。

引用我的评论:

如果您需要将大量值传递给查询,我建议使用 Table-Type 参数。但是如果你真的需要传递 1M+ 的值,那么听起来你的设计有问题。列出你不想要的值可能会更好。

编辑:添加到我的评论中,许多人(包括我自己)更喜欢使用EXISTS 而不是IN。因此,而不是像这样的查询:

FROM YourTable YT
WHERE YT.YourColumn IN (SELECT OT.YourColumn
                        FROM OtherTable OT)

你会有这样的查询:

FROM YourTable YT
WHERE EXISTS (SELECT 1
              FROM OtherTable OT
              WHERE OT.YourColumn = YT.YourColumn)

【讨论】:

第二个问题是什么,这是在 db 中检查 1m 数据和另外 1m 数据的最佳方法 答案涵盖了@jithink,文档指出“将IN 列表中的项目存储在表中,并在IN 子句中使用SELECT 子查询。” 而我state "如果需要向查询传递大量值,我建议使用 Table-Type 参数"。就个人而言,我也更喜欢使用EXISTS 而不是IN @jithink 我用过EXISTS。有关性能和比较的一些有趣辩论,请参阅这些帖子 1、2、3。

以上是关于“In”子句可以处理的项目的最大限制的主要内容,如果未能解决你的问题,请参考以下文章

Informix:IN 子句中的项目数量限制?

Redshift:“IN 子句”中的最大项目数?

MongoDB 的 $in 子句是不是有参数数量的最大限制

MongoDB 的 $in 子句是不是有参数数量的最大限制

如何将超过 1000 个值放入 Oracle IN 子句 [重复]

SQL IN 逗号分隔参数与内部查询