SQL Server中“IN”子句的限制

74

请问有人知道IN子句用于匹配测试的表达式列表中可以拥有多少个值的限制吗?


http://msdn.microsoft.com/en-us/library/ms143432.aspx - xdazz
11
你不应该编写会让你接近极限的代码,因为当 n 变得很大时,使用 in (aa,a2, ..., an) 会变得非常低效。尽可能通过更好的机制来控制查询选择,例如等效的 exists 子句。 - Gary Walker
5个回答

57

是的,有一个限制,但Microsoft只指定它在“数千”范围内:

在IN子句中明确包含大量值(由逗号分隔的许多千个值)可能会消耗资源并返回错误8623或8632。为了解决这个问题,在IN列表中将项目存储在表中,并在IN子查询中使用SELECT子查询。

详细查看这些错误,我们可以发现此限制不仅适用于IN,而且适用于查询复杂性:

错误8623:

查询处理器已耗尽内部资源,无法生成查询计划。这是一种罕见事件,仅预期出现在极其复杂的查询或涉及非常多的表或分区的查询中。请简化查询。如果您认为收到了此消息,请联系客户支持服务以获取更多信息。

错误8632:

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


1
https://dba.stackexchange.com/a/228982/6548 表示它有32768个项目。 - Rory

24

这不是特定的问题,但与查询计划生成器超出内存限制有关。经过多次确认,在处理几千个数据时,通常会出现错误,但可以通过先将值插入到表中,然后重新构造查询语句来解决。

select * from b where z in (select z from c) 

您想在in子句中使用的值在c表中。我们成功地使用了100万个值的in子句。


13

根据您使用的数据库引擎,指令的长度可能有限制。

SQL Server的限制非常大:

SQL Server的最大容量规格

因此,对于大型IN子句,最好创建一个临时表,插入值并进行JOIN。 这样也可以更快地工作。

虽然存在限制,但是您可以将值拆分为单独的in()块。

Select * 
From table 
Where Col IN (123,123,222,....)
or Col IN (456,878,888,....)

在2008中使用表值参数,或使用此处描述的某种方法。

SQL Server 2005中的数组和列表


7
根据您执行查询的方式(JDBC、Hibernate、某种SQL-GUI),以及使用文字值而不是子查询where X in (1, 2, 3...) - 您可能会遇到以下错误:

在此 RPC 请求中提供了太多参数。最大值为2100。

因此,在这些情况下,限制将为2100(甚至在其他参数也存在时,限制可能更少)。

0

SQL Server JDBC驱动程序有2100的限制,并抛出SQLServerException异常:

Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The incoming request has too many parameters. The server supports a maximum of 2100 parameters. Reduce the number of parameters and resend the request.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:265) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1676) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement(SQLServerPreparedStatement.java:615) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:537) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7730) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:3786) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:268) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:242) ~[mssql-jdbc-10.2.1.jre8.jar:na]
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeQuery(SQLServerPreparedStatement.java:456) ~[mssql-jdbc-10.2.1.jre8.jar:na]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接