表值构造函数Select中的最大行数限制

我有一个Table Valued Constructor通过它可以选择大约1 million条记录。 它将被用来update另一个表。

SELECT *
FROM   (VALUES (100,200,300),
               (100,200,300),
               (100,200,300),
               (100,200,300),
               .....
               ..... --1 million records
               (100,200,300)) tc (proj_d, period_sid, val) 

这是我的原始查询:https://www.dropbox.com/s/ezomt80hsh36gws/TVC.txt?dl=0#

当我做了上面的select它只是显示查询完成并显示错误信息。

更新:尝试使用TRY/CATCH块捕获错误消息或错误编号,但不会像以前的图像那样使用相同的错误

BEGIN try
    SELECT *
    FROM   (VALUES (100,200,300),
                    (100,200,300),
                    (100,200,300),
                    (100,200,300),
                    .....
                    ..... --1 million records
                    (100,200,300)) tc (proj_d, period_sid, val) 
END try

BEGIN catch
    SELECT Error_number(),
           Error_message()
END catch 

为什么它没有执行, Select Table Valed构造函数有任何限制。 我知道Insert它是1000但我在这里选择。


没有相关的硬编码限制(65,536 * 4KB的网络数据包大小为268 MB,并且您的脚本长度远不及此值),但不宜将此方法用于大量行。

您看到的错误是由客户端工具而不是SQL Server引发的。 如果在动态SQL编译中构建SQL字符串,至少能够成功启动

DECLARE @SQL NVARCHAR(MAX) = '(100,200,300),
';

SELECT @SQL = 'SELECT * FROM (VALUES ' + REPLICATE(@SQL, 1000000) + '
(100,200,300)) tc (proj_d, period_sid, val)';

SELECT @SQL AS [processing-instruction(x)]
FOR XML PATH('')

SELECT DATALENGTH(@SQL) / 1048576.0 AS [Length in MB] --30.517705917

EXEC(@SQL);

虽然我在约30分钟的编译时间之后杀死了上述内容,但仍然没有产生任何结果。 字面值需要作为常量表存储在计划本身内部,而SQL Server也花费大量时间来尝试派生它们的属性。

SSMS是一个32位应用程序,并在分析批处理时抛出std::bad_alloc异常

在这里输入图像描述

它试图将元素推送到已达到容量的令牌矢量上,并且由于无法获得足够大的连续区域的内存而导致其调整大小的尝试失败。 所以这个说法甚至不会让它达到服务器。

矢量容量每次增长50%(即按照这里的顺序)。 矢量需要增长的能力取决于代码的布局方式。

以下需要从19个容量增加到28个。

SELECT * FROM 
(VALUES 
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300),
(100,200,300)) tc (proj_d, period_sid, val)

以下仅需要2的大小

SELECT * FROM (VALUES (100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300),(100,200,300)) tc (proj_d, period_sid, val)

以下需要大于63和小于等于94的容量。

SELECT *
FROM   (VALUES 
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300),
      (100,
       200,
       300)
       ) tc (proj_d, period_sid, val) 

对于如情况1所布置的一百万行,向量容量需要增长到3,543,306。

您可能会发现以下任一项都会允许客户端解析成功。

  • 减少换行次数。
  • 重新启动SSMS时,希望在地址空间碎片较少时请求连续大内存成功。
  • 但是,即使您成功将其发送到服务器,它也只会在执行计划生成过程中最终导致服务器死机,如上所述。

    使用导入导出向导加载表格会更好。 如果你必须在TSQL中做到这一点,你会发现把它分成更小的批次和/或使用另一种方法比如shreding XML将比表值构造器更好。 例如,以下内容在我的机器上以13秒为单位执行(尽管如果使用SSMS,您仍然可能需要分成多个批次而不是粘贴大量的XML字符串文本)。

    DECLARE @S NVARCHAR(MAX) = '<x proj_d="100" period_sid="200" val="300" />
    ' ; 
    
    DECLARE @Xml XML = REPLICATE(@S,1000000);
    
    SELECT 
        x.value('@proj_d','int'),
        x.value('@period_sid','int'),
        x.value('@val','int')
    FROM @Xml.nodes('/x') c(x)
    

    检查此查询限制:https://msdn.microsoft.com/en-us/library/ms143432.aspx

    链接地址: http://www.djcxy.com/p/37027.html

    上一篇: Table Valued Constructor Maximum rows limit in Select

    下一篇: install X509 certificate programmatically in my case