The best method is not to delete at all.这可能会非常慢,导致大量事务日志(log)增长,如果您try 将日志(log)设置为SHRINK
,则可能会遇到更多问题.
相反,将需要的数据复制到一个新表中,然后执行切换并删除另一个表.
做切换的最好方法不是使用sp_rename
,而是使用ALTER TABLE SWITCH
.为此,最好使用两个单独的临时表,它们的定义与主表完全相同.
将您的数据库切换到大容量日志(log),这意味着大型插入获得的日志(log)记录要少得多.使用INSERT
上的TABLOCK
提示进行最小日志(log)记录,以及并行插入.
CREATE TABLE Staging1 (
-- exact same columns, types, nullable
-- exact same primary, unique, foreign keys, check constraints
);
CREATE TABLE Staging2 (
-- exact same columns, types, nullable
-- exact same primary, unique, foreign keys, check constraints
);
INSERT Staging2 WITH (TABLOCK)
(ColumsHere)
SELECT ColumnsHere
FROM YourTable
WHERE whatever; --all data to keep
如果您经常插入,那么您需要找到一种在复制时保持新表同步的方法(可能使用触发器).您也可以使用SNAPSHOT ISOLATION
来避免挡住旧桌子.
现在您可以进行切换了
SET XACT_ABORT, NOCOUNT ON; -- force immediate rollback if session is killed
BEGIN TRAN;
ALTER TABLE YourTable SWITCH TO Staging1
WITH ( WAIT_AT_LOW_PRIORITY ( MAX_DURATION = 1 MINUTES, ABORT_AFTER_WAIT = BLOCKERS ));
-- not strictly necessary to use WAIT_AT_LOW_PRIORITY but better for blocking
-- use SELF instead of BLOCKERS to kill your own session
ALTER TABLE Staging2 SWITCH TO YourTable
WITH (WAIT_AT_LOW_PRIORITY (MAX_DURATION = 0 MINUTES, ABORT_AFTER_WAIT = BLOCKERS));
-- force blockers off immediately
COMMIT TRAN;
最后删除或删除旧数据
TRUNCATE TABLE Staging1;
所有这些切换都完全是元数据的,而且非常非常快(大约几毫秒).它只占极少量的伐木量.您还可以通过为新的数据大小重新构建索引而受益.
如果您的磁盘上没有足够的空间,您可以添加一个临时磁盘(内部/外部SSD驱动器等),并将FILE
添加到同一文件组中.然后,在截断旧数据之后,可以从文件组as explained here中删除该文件.不要创建新的文件组,在这种情况下,此代码将不起作用.