在午夜,我通过在存储过程中执行以下操作来归档SQL Server 2008表:

INSERT INTO archive(col1, col2....)
select col1, col2...
from tablename
where date <= @endDate

delete from tablename where date <= @enddate

这是表模式。我显然更改了列名。存档表的结构完全相同。
[col1] [uniqueidentifier] NOT NULL,
[col1] [bigint] NOT NULL,
[col1] [nvarchar](255) NOT NULL,
[col1] [nvarchar](255) NOT NULL,
[col1] [datetime] NOT NULL,
[col1] [nvarchar](75) NULL,
[col1] [nvarchar](255) NULL,
[col1] [nvarchar](255) NULL,
[col1] [nvarchar](255) NULL,
[col1] [nvarchar](255) NULL,
[col1] [nvarchar](50) NULL,
[col1] [nvarchar](50) NULL,
[col1] [nvarchar](1000) NULL,
[col1] [nvarchar](2) NULL,
[col1] [nvarchar](255) NULL,
[col1] [nvarchar](255) NULL,

该表通常具有大约100,000-150,0000行以及几个索引,并且在我尝试执行此存档时仍在向其中写入信息。

此过程最快需要6分钟,而最慢需要13分钟。

有更快的方法吗?

最佳答案

分区是最快的技术,但增加了复杂性,需要Enterprise Edition。

另一种方法是通过使用OUTPUT子句将DELETE和INSERT组合为一个语句。 http://msdn.microsoft.com/en-us/library/ms177564.aspx。带OUTPUT子句的DELETE比单个INSERT / DELETE语句要快。

DELETE FROM tablename
    OUTPUT DELETED.Col1, DELETED.col2, DELETED.col3 DELETED.col4 -- etc
    INTO archive ( col1, col2, col3, col4 )
 WHERE date <= @enddate;

如果由于并发插入而导致阻塞问题,那么可以通过循环处理上述语句:
DECLARE @i int
SET @i = 1
WHILE @i > 0
BEGIN
    DELETE  top (1000) FROM tablename
        OUTPUT DELETED.Col1, DELETED.col2, DELETED.col3 DELETED.col4 -- Eric
        INTO archive ( col1, col2, col3, col4 )
    WHERE date <= @enddate
    SET @i = @@rowcount
END

附加说明:输出表有一些限制。它不能具有触发器,不能包含在外键中或具有检查约束。

关于sql - 无论如何要加快大表的归档,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15853078/

10-13 08:05