首页 文章

SQL Server查询的最大大小? IN子句?有更好的方法[重复]

提问于
浏览
86

可能重复: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 回答

  • 69

    每个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是另一种可行的解决方案:

    SELECT ...
    FROM Table
    JOIN (
       SELECT x.value(N'.',N'uniqueidentifier') as guid
       FROM @values.nodes(N'/guids/guid') t(x)) as guids
     ON Table.guid = guids.guid;
    
  • 35

    公开的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项目,花了一些时间然后下降:

    消息8623,级别16,状态1,行1查询处理器耗尽内部资源,无法生成查询计划 . 这是一种罕见的事件,仅适用于引用大量表或分区的极其复杂的查询或查询 . 请简化查询 . 如果您认为错误地收到了此消息,请与客户支持服务联系以获取更多信息 .

    所以30k是可能的,但仅仅因为你可以做到 - 并不意味着你应该:)

    编辑:由于其他问题继续 .

    50k工作了,但60k退出了,所以在我的测试台上的某处某处 .

    关于如何在不使用大的in子句的情况下连接值,我个人会创建一个临时表,将值插入到临时表中,对其进行索引,然后在连接中使用它,为其提供最佳机会优化联接 . (在临时表上生成索引将为其创建统计数据,这将有助于优化器作为一般规则,尽管1000 GUID不会完全找到非常有用的统计数据 . )

  • 7

    每批,65536 * Network Packet Size,这是4k所以256 MB

    但是,IN会在此之前停止,但这并不准确 .

    您最终会遇到内存错误,但我无法回想起确切的错误 . 无论如何,巨大的IN将是低效的 .

    编辑:Remus提醒我:错误是关于“堆栈大小”

  • 12

    您可以将GUID加载到临时表中然后执行

    ... WHERE var IN SELECT guid FROM #scratchtable
    

相关问题