2

在午夜,我通过在存储过程中执行此操作来归档 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 分钟。

有没有更快的方法来做到这一点?

4

2 回答 2

6

分区是最快的技术,但会增加复杂性并且需要企业版。

另一种方法是使用 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    

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

于 2013-04-06T17:30:02.363 回答
1

处理归档的更合适的方法是创建和管理分区。

有几个可用的指南和教程,例如:http: //blogs.msdn.com/b/felixmar/archive/2011/08/29/partitioning-amp-archiving-tables-in-sql-server-part-2 -split-merge-and-switch-partitions.aspx

于 2013-04-06T16:19:22.510 回答