在有限的(1000 行)块中移动 SQL Server 数据
我正在编写一个基于日期时间列归档 SQL Server 表中的行的进程.我想移动日期在 X 之前的所有行,但问题是每个日期有数百万行,所以对每个日期执行 BEGIN TRANSACTION...INSERT...DELETE...COMMIT 需要太长时间,并为其他用户锁定数据库.
I'm writing a process that archives rows from a SQL Server table based on a datetime column. I want to move all the rows with a date before X, but the problem is that there are millions of rows for each date, so doing a BEGIN TRANSACTION...INSERT...DELETE...COMMIT for each date takes too long, and locks up the database for other users.
有没有办法可以分小块做?也许使用 ROWCOUNT 或类似的东西?
Is there a way that I can do it in smaller chunks? Maybe using ROWCOUNT or something like that?
我最初考虑过这样的事情:
I'd originally considered something like this:
SET ROWCOUNT 1000
DECLARE @RowsLeft DATETIME
DECLARE @ArchiveDate DATETIME
SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)
WHILE @ROWSLEFT IS NOT NULL
BEGIN
INSERT INTO EventsBackups
SELECT top 1000 * FROM Events
DELETE Events
SET @ROWSLEFT = (SELECT TOP 1 dtcol FROM Events WHERE dtcol <= @ArchiveDate)
END
但后来我意识到我不能保证我正在删除的行是我刚刚备份的行.或者我可以...?
But then I realized that I can't guarantee that the rows I'm deleting are the ones I just backed up. Or can I...?
更新:我考虑过的另一个选项是添加一个步骤:
UPDATE: Another options I'd considered was adding a step:
- 将符合我的日期条件的前 1000 行选择到临时表中
- 开始交易
- 从临时表插入存档表
- 从源表中删除,跨列加入临时表
- 提交交易
- 重复 1-5 直到没有符合日期条件的行
有人知道这个系列的费用与下面讨论的其他一些选项相比如何吗?
Does anybody have an idea for how the expense of this series might compare to some of the other options discussed below?
详细信息:我正在使用 SQL 2005,因为有人问过.
DETAIL: I'm using SQL 2005, since somebody asked.
推荐答案
只需插入DELETE的结果:
Just INSERT the result of the DELETE:
WHILE 1=1
BEGIN
WITH EventsTop1000 AS (
SELECT TOP 1000 *
FROM Events
WHERE <yourconditionofchoice>)
DELETE EventsTop1000
OUTPUT DELETED.*
INTO EventsBackup;
IF (@@ROWCOUNT = 0)
BREAK;
END
这是原子的和一致的.
相关文章