首页 文章

SQL Server中的插入速度确实很慢

提问于
浏览
0

我需要帮助将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 回答

  • 0

    由于您希望在 A 中插入 B 中的所有行,因此不需要使用 exists . 问题变成跟踪先前批次中已传输的行 . 以下示例生成行号并使用它将行分组到批处理中 . 如果行号按现有索引排序,那么 select 侧不应该需要排序 .

    -- Sample data.
    declare @A as Table ( Col1 Int, Col2 Int );
    
    declare @B as Table ( Col1 Int, Col2 Int );
    insert into @B ( Col1, Col2 ) values
      ( 1, 1 ), ( 1, 2 ), ( 1, 3 ), ( 1, 4 ), ( 1, 5 ),
      ( 2, 1 ), ( 2, 2 ), ( 2, 3 ), ( 2, 4 ), ( 2, 5 );
    
    -- Rows to transfer in each batch.
    declare @BatchSize as Int = 5;
    -- First row to transfer in the current batch.
    declare @BatchMark as Int = 1;
    -- Count of rows processed.
    declare @RowsProcessed as Int = 1;
    
    -- Process the batches.
    while @RowsProcessed > 0
      begin
      insert into @A ( Col1, Col2 )
        select Col1, Col2
          from ( select Col1, Col2, Row_Number() over ( order by Col1, Col2 ) as RN from @B ) as PH
          where @BatchMark <= RN and RN < @BatchMark + @BatchSize;
      select @RowsProcessed = @@RowCount, @BatchMark += @BatchSize;
      select * from @A; -- Show progress.
      end;
    

    替代方案包括向 B 表添加标志列以标记已处理的行,使用 B 表中的现有 id 来跟踪已处理的最大值,使用附加表来跟踪已处理行的索引值,从 B 删除已处理的行,......

    一些output条款可能对某些替代方案有用 .

    在传输数据之前使用合适的填充因子重建索引可能会有所帮助 . 见here . 这取决于您的问题中没有的索引值的知识 .

相关问题