SQL Mass删除

时间:2009-10-07 14:15:05

标签: sql logging truncate sql-delete

我正在尝试缩小某些数据库,以便我的开发人员可以将它们加载到本地计算机上。我已经确定了几个包含历史数据(10年以上)的表,如果我删除超过X天的记录,这将大大减少整体数据库大小(50%或更多)。

我正在使用的删除语句如下所示,但我的问题是,如何提高此删除语句的速度?数据库已经采用简单的日志记录格式,但日志仍然使用delete语句增长。有更好的记录方法吗?

这样做会更好吗?  

      
  1. 将我要保留的数据从当前表复制到临时表中,   
  2. 截断主表,   
  3. 将数据从temp移回主数据库,   
  4. 收缩日志,   
  5. 完成所有需要缩小的表后缩小数据库。

查询示例:

DELETE FROM LoginAttempts WHERE DateAttempt <= GETDATE() - 30

4 个答案:

答案 0 :(得分:2)

TRUNCATECREATE AS SELECT比删除整个表要快得多,因为它们可以减少重做日志记录。

但它们是DDL命令,在某些系统中无法回滚。

但是,如果要删除的行数很少,DELETE可能会更快。

如果要删除一半行,那么第一个选项很可能会更快,至少在Oracle中。

答案 1 :(得分:1)

您选择移出要保留的数据非常有效,但只有当保留的数量与要移除的数据相比较小时才有效。

为了更有效地执行删除,您可能希望批处理删除操作,该操作仅删除前1000行(不使用订单子句!),以便每个删除事务的大小保持较小并且不保存锁/使用很多温度等。

删除所有数据后缩小数据库会将索引分段为btw,如果你必须缩小文件组,将数据移动到另一个文件组并删除原始文件,如果可以的话,任何缩小都会破坏你,导致你重新索引并再次使用更多空间(你可以冲洗重复它无济于事)

答案 2 :(得分:0)

尽可能使用truncate,因为它的速度更快。但是,当有外键引用该表时,这将不起作用。

在大表上执行这些类型的删除语句时,只需在临时表中选择最后N天,删除表,重新创建和插入就可以更快。但是,如果你有外键,这可能会变得棘手。

我在事务日志上最大化磁盘空间时遇到了问题,因此我有时使用while循环,一次只删除N行。

还应确保您的数据库使用简单事务日志,您可能还需要设置自动缩小。

答案 3 :(得分:0)

我认为你想要将想要保存的数据提取到临时表中,截断原始表,然后将其放回原点。

您还可以使用提取的数据创建新表,删除新表并将其重命名为原始表名。这似乎更容易出错,但如果你在维护期间做这种工作,那么也许没关系。