我正在尝试缩小某些数据库,以便我的开发人员可以将它们加载到本地计算机上。我已经确定了几个包含历史数据(10年以上)的表,如果我删除超过X天的记录,这将大大减少整体数据库大小(50%或更多)。
我正在使用的删除语句如下所示,但我的问题是,如何提高此删除语句的速度?数据库已经采用简单的日志记录格式,但日志仍然使用delete语句增长。有更好的记录方法吗?
这样做会更好吗?
查询示例:
DELETE FROM LoginAttempts WHERE DateAttempt <= GETDATE() - 30
答案 0 :(得分:2)
TRUNCATE
和CREATE AS SELECT
比删除整个表要快得多,因为它们可以减少重做日志记录。
但它们是DDL
命令,在某些系统中无法回滚。
但是,如果要删除的行数很少,DELETE
可能会更快。
如果要删除一半行,那么第一个选项很可能会更快,至少在Oracle
中。
答案 1 :(得分:1)
您选择移出要保留的数据非常有效,但只有当保留的数量与要移除的数据相比较小时才有效。
为了更有效地执行删除,您可能希望批处理删除操作,该操作仅删除前1000行(不使用订单子句!),以便每个删除事务的大小保持较小并且不保存锁/使用很多温度等。
删除所有数据后缩小数据库会将索引分段为btw,如果你必须缩小文件组,将数据移动到另一个文件组并删除原始文件,如果可以的话,任何缩小都会破坏你,导致你重新索引并再次使用更多空间(你可以冲洗重复它无济于事)
答案 2 :(得分:0)
尽可能使用truncate,因为它的速度更快。但是,当有外键引用该表时,这将不起作用。
在大表上执行这些类型的删除语句时,只需在临时表中选择最后N天,删除表,重新创建和插入就可以更快。但是,如果你有外键,这可能会变得棘手。
我在事务日志上最大化磁盘空间时遇到了问题,因此我有时使用while循环,一次只删除N行。
还应确保您的数据库使用简单事务日志,您可能还需要设置自动缩小。
答案 3 :(得分:0)
我认为你想要将想要保存的数据提取到临时表中,截断原始表,然后将其放回原点。
您还可以使用提取的数据创建新表,删除新表并将其重命名为原始表名。这似乎更容易出错,但如果你在维护期间做这种工作,那么也许没关系。