Table Valued Constructor 最大行数限制 Select
Table Valued Constructor Maximum rows limit in Select
我有一个 Table Valued Constructor
,通过它我正在选择 1 million
条记录。它将用于 update
另一个 table。
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
但我在这里选择。
检查查询限制:
https://msdn.microsoft.com/en-us/library/ms143432.aspx
没有相关的硬编码限制(65,536 * 4KB 的网络数据包大小为 268 MB,您的脚本长度远不及此),但不建议对大量行使用此方法。
您看到的错误是由客户端工具而非 SQL 服务器抛出的。如果在动态中构建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 分钟的编译时间后杀死了上面的代码,但它仍然没有产生一行。字面值需要作为常量的 table 存储在计划本身中,并且 SQL 服务器也花费 a lot of time 尝试派生关于它们的属性。
SSMS 是一个 32 位应用程序,在解析批处理时抛出 std::bad_alloc
异常
它试图将一个元素推入已达到容量的令牌向量,但由于没有足够大的连续内存区域,它尝试调整大小失败。因此,该声明甚至从未到达服务器。
向量容量每次增长50%(即在the sequence here之后)。向量需要增长到的容量取决于代码的布局方式。
以下需要从 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,希望在地址 space 碎片较少的情况下成功请求大的连续内存。
然而,即使您成功将它发送到服务器,它也只会在执行计划生成期间终止服务器,如上所述。
您最好使用导入导出向导来加载 table。如果您必须在 TSQL 中执行此操作,您会发现使用另一种方法(例如切碎 XML 将其分成更小的批次 and/or 将比 Table Valued Constructors 执行得更好。例如,以下代码在我的机器上执行时间为 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)
我有一个 Table Valued Constructor
,通过它我正在选择 1 million
条记录。它将用于 update
另一个 table。
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
但我在这里选择。
检查查询限制: https://msdn.microsoft.com/en-us/library/ms143432.aspx
没有相关的硬编码限制(65,536 * 4KB 的网络数据包大小为 268 MB,您的脚本长度远不及此),但不建议对大量行使用此方法。
您看到的错误是由客户端工具而非 SQL 服务器抛出的。如果在动态中构建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 分钟的编译时间后杀死了上面的代码,但它仍然没有产生一行。字面值需要作为常量的 table 存储在计划本身中,并且 SQL 服务器也花费 a lot of time 尝试派生关于它们的属性。
SSMS 是一个 32 位应用程序,在解析批处理时抛出 std::bad_alloc
异常
它试图将一个元素推入已达到容量的令牌向量,但由于没有足够大的连续内存区域,它尝试调整大小失败。因此,该声明甚至从未到达服务器。
向量容量每次增长50%(即在the sequence here之后)。向量需要增长到的容量取决于代码的布局方式。
以下需要从 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,希望在地址 space 碎片较少的情况下成功请求大的连续内存。
然而,即使您成功将它发送到服务器,它也只会在执行计划生成期间终止服务器,如上所述。
您最好使用导入导出向导来加载 table。如果您必须在 TSQL 中执行此操作,您会发现使用另一种方法(例如切碎 XML 将其分成更小的批次 and/or 将比 Table Valued Constructors 执行得更好。例如,以下代码在我的机器上执行时间为 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)