可能重复:T-SQL WHERE col IN(...)
SQL Server查询的最大大小是多少? (字符数)
IN子句的最大大小?我想我看到有关于Oracle有1000项限制的东西,但你可以用ANDing 2 INs来解决这个问题 . SQL Server中的类似问题?
UPDATE 那么,如果我需要从另一个系统(非关系数据库)中获取1000个GUID并对SQL Server执行“JOIN in code”,那么最好的方法是什么?是否将1000个GUID列表提交给IN子句?还是有另一种技术可以更有效地运作?
我没有测试过这个,但我想知道我是否可以将GUID作为XML文档提交 . 例如
<guids>
<guid>809674df-1c22-46eb-bf9a-33dc78beb44a</guid>
<guid>257f537f-9c6b-4f14-a90c-ee613b4287f3</guid>
</guids>
然后对Doc和Table做一些XQuery JOIN . 效率低于1000项IN条款?
4 回答
每个SQL批处理都必须符合Batch Size Limit:65,536 *网络包大小 .
除此之外,您的查询受运行时条件的限制 . 它通常会耗尽堆栈大小,因为x IN(a,b,c)只是x = a OR x = b OR x = c,它创建一个类似于x = a OR的表达式树(x = b OR(x) = c)),因此大量的OR变得非常深 . SQL 7会命中SO at about 10k values in the IN,但是现在的堆栈更深(因为x64),所以它可以非常深入 .
Update
您已经找到了Erland关于将列表/数组传递给SQL Server主题的文章 . 使用SQL 2008,您还可以使用Table Valued Parameters,它允许您将整个DataTable作为单个表类型参数传递并加入其中 .
XML和XPath是另一种可行的解决方案:
公开的SQL Server最大值http://msdn.microsoft.com/en-us/library/ms143432.aspx(这是2008版)
SQL查询可以是varchar(max),但显示为限制为65,536 *网络数据包大小,但即使这样,最有可能使您绊倒的是每个查询2100个参数 . 如果SQL选择参数化in子句中的文字值,我认为你会先达到这个限制,但我没有测试过它 .
编辑:测试它,即使在强制参数化下它幸存下来 - 我敲了一个快速测试并让它在In子句中执行30k项目 . (SQL Server 2005)
在100k项目,花了一些时间然后下降:
所以30k是可能的,但仅仅因为你可以做到 - 并不意味着你应该:)
编辑:由于其他问题继续 .
50k工作了,但60k退出了,所以在我的测试台上的某处某处 .
关于如何在不使用大的in子句的情况下连接值,我个人会创建一个临时表,将值插入到临时表中,对其进行索引,然后在连接中使用它,为其提供最佳机会优化联接 . (在临时表上生成索引将为其创建统计数据,这将有助于优化器作为一般规则,尽管1000 GUID不会完全找到非常有用的统计数据 . )
每批,65536 * Network Packet Size,这是4k所以256 MB
但是,IN会在此之前停止,但这并不准确 .
您最终会遇到内存错误,但我无法回想起确切的错误 . 无论如何,巨大的IN将是低效的 .
编辑:Remus提醒我:错误是关于“堆栈大小”
您可以将GUID加载到临时表中然后执行