我需要帮助将200万行插入表中 . 我插入的表有40亿行,我插入的表有200万行 . 插入速率约为每分钟190行 .
DECLARE @BatchSize INT = 5000
WHILE 1 = 1
BEGIN
INSERT INTO [dbo].[a] ([a].[col1], [a].[col2], [a].[adate], [a].[importdate])
SELECT TOP(@BatchSize)
b.col1,
b.col2,
b.adate,
b.importdate
FROM
b
WHERE
NOT EXISTS (SELECT 1
FROM dbo.[a]
WHERE [a].col1 = b.col1
AND [a].col2 = b.col2
AND [a].adate = b.adate)
--AND [sent].aDate > getdate()-10)
IF @@ROWCOUNT < @BatchSize BREAK
END;
在上面的查询中,在表a中,col1和col2以及col3是主键(非群集) . 我想从表b中插入表a中的每条记录...
表a有3个索引,一个是col1.col2,第二个是col1,col2,col3,第三个是col1 ......
任何人都可以提出让它更快的想法吗?
我在SQL Server 2008 R2上有128 Gb RAM .
谢谢
1 回答
由于您希望在
A
中插入B
中的所有行,因此不需要使用exists
. 问题变成跟踪先前批次中已传输的行 . 以下示例生成行号并使用它将行分组到批处理中 . 如果行号按现有索引排序,那么select
侧不应该需要排序 .替代方案包括向
B
表添加标志列以标记已处理的行,使用B
表中的现有id
来跟踪已处理的最大值,使用附加表来跟踪已处理行的索引值,从B
删除已处理的行,......一些output条款可能对某些替代方案有用 .
在传输数据之前使用合适的填充因子重建索引可能会有所帮助 . 见here . 这取决于您的问题中没有的索引值的知识 .