我有一个返回大约 1000 万行的选择查询,然后我需要将它们插入到一个新表中。
我希望性能没问题,所以我想将它们分批 10000 插入到新表中。举个例子,我在下面创建了一个简单的选择查询
Insert into new table
Select top 10000 * from applications
但现在我需要获取接下来的 10000 行并插入它们。有没有办法遍历百万行以批量插入 10000 行?我正在使用 sql server 2008。
我有一个返回大约 1000 万行的选择查询,然后我需要将它们插入到一个新表中。
我希望性能没问题,所以我想将它们分批 10000 插入到新表中。举个例子,我在下面创建了一个简单的选择查询
Insert into new table
Select top 10000 * from applications
但现在我需要获取接下来的 10000 行并插入它们。有没有办法遍历百万行以批量插入 10000 行?我正在使用 sql server 2008。
通过批量处理它可能不会更快。大概是相反的吧。大多数时候,一个语句是最快的版本。它可能只需要大量的临时空间和日志。但最快的是用挂钟测量的。
这样做的原因是 SQL Server 自动构建了一个好的计划,可以一次有效地批量处理所有工作。
回答您的问题:您编写的语句会产生未定义的行,因为表没有顺序。您可能应该添加一个集群键,如 ID 列。这样,您可以使用 while 循环沿着表格前进,每次执行以下操作:
INSERT ...
SELECT TOP 10000 *
FROM T
WHERE ID > @lastMaxID
ORDER BY ID
请注意,这ORDER BY
是正确性所必需的。
使用 CTE 或 While 循环插入类似批次
;WITH q (n) AS (
SELECT 1
UNION ALL
SELECT n + 1
FROM q
WHERE n < 10000
)
INSERT INTO table1
SELECT * FROM q
或者
DECLARE @batch INT,
@rowcounter INT,
@maxrowcount INT
SET @batch = 10000
SET @rowcounter = 1
SELECT @maxrowcount = max(id) FROM table1
WHILE @rowcounter <= @maxrowcount
BEGIN
INSERT INTO table2 (col1)
SELECT col1
FROM table1
WHERE 1 = 1
AND id between @rowcounter and (@rowcounter + @batch)
-- Set the @rowcounter to the next batch start
SET @rowcounter = @rowcounter + @batch + 1;
END
我不会批量处理 1000 万条记录。
如果您正在批处理插入,请使用索引字段来定义您的批处理。
DECLARE @intFlag INT
SET @intFlag = 1
WHILE (@intFlag <=10000000)
BEGIN
INSERT INTO yourTable
SELECT *
FROM applications
WHERE ID BETWEEN @intFlag AND @IntFlag + 9999
SET @intFlag = @intFlag + 10000
END
GO
作为一个选项,您可以通过 bcp 将查询导出到平面文件,然后将其批量导入到表中。BULK IMPORT 语句具有 BATCHSIZE 选项来限制行数。在您的情况下, BATCHSIZE =10000 将起作用。
还有另一种创建 SSIS 包的选项。在 OLE DB 目标中选择快速加载并在“Rows per batch:”中定义 10000 行数。这可能是最简单的解决方案。