【问题标题】:Removal of 30-40 millions record without affecting performance在不影响性能的情况下删除 30-40 百万条记录
【发布时间】:2011-09-06 21:26:14
【问题描述】:

我有一个在完全恢复中运行的 SQL Server 数据库。我需要删除数据(大约 30-4000 万条记录),但我不能让数据库脱机,因为它一直在使用。我也无法将其切换到简单恢复模式以防万一发生任何事情并且我们丢失了实时数据。当我尝试以小块(大约 200 万行)删除数据时,事务日志变得非常大并导致过程变得非常缓慢。由于备份作业在夜间运行,我只有很短的时间范围。

有人对我如何做到这一点有任何想法吗?我考虑将表复制到另一个数据库(在简单恢复模式下),然后删除数据。这是个好主意吗?

有 3 张桌子有问题。活动、事件和目标。它的事件表中有数百万条记录,这是需要时间删除的。所有这些都通过 Id 列具有必要的关系。

【问题讨论】:

  • 你试过更小的块吗?
  • 不幸的是,这些“块”是我能得到的最小的。
  • 删除后会剩下多少行?
  • 与大多数数据库问题一样,您应该包括架构,在这种情况下,包括关键字段中的数据分布。您说“这些‘块’尽可能小”,但根据所提供的信息,我们不知道
  • @Ian:是的,企业版。

标签: sql-server-2008 large-data-volumes


【解决方案1】:

必须使用小块,否则您的事务日志会增加

将记录 30-40 百万次删除中的每一次。如果您创建一个新表并复制“保留”行,您仍将拥有 50 多万条记录的行。简单恢复与完全恢复无关紧要:每次删除/插入都会被记录

如果日志在简单恢复中增加,那么我怀疑您是在事务中执行此操作。所以仍然记录了 30-4000 万次删除,即使是在简单的恢复中也是如此,因为它可能都必须回滚。

对于更简单的恢复中没有事务的 40 x 100 万次删除,您可以使用 CHECKPOINT 来帮助整理日志

更多信息请见Bulk DELETE on SQL Server 2008 (Is there anything like Bulk Copy (bcp) for delete data?)

但是类似:

SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
BEGIN
    CHECKPOINT
    --Edit: must be last to set @@ROWCOUNT
    DELETE TOP (1000000) MyTable WHERE ...
END

流程:

  • 完整备份
  • 将恢复更改为简单
  • 删除
  • 将恢复更改为完全(或之前的状态)
  • 完整备份

如果你坚持在一个短窗口中一次性删除 30+ 百万行,你没有太多其他选择......

【讨论】:

  • @gbn:这是很好的信息。我不是一次性删除 30-4000 万条记录,它只是每个活动 1-200 万个小块,但总数是 30-4000 万行。
  • @gbn:如果我使用CHECKPOINT并取消查询,这仍然是commit那些记录还是会被回滚?
  • 两者都不:它只会回滚当前删除批次中的那些行。任何已删除的行都将保持删除状态。 CHECKPOINT 仅用于触发日志整理
  • @gbn:在WHILE循环中,这会在每次迭代后更新@@ROWCOUNT吗?
  • @gbn:当我使用CHECKPOINT时,这是否消除了围绕while循环的transaction的需要?
【解决方案2】:

您使用什么标准来选择要删除的 30-40 百万行?如果这是相当简单的事情(例如“超过 10 天”),那么您可以使用 SQL Server 的表分区机制。有一些有据可查的技术(见下面的链接)关于分区切换来处理与您类似的用例。

pjjH

http://msdn.microsoft.com/en-us/library/ms191160%28v=sql.100%29.aspx

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 2019-11-16
    • 2023-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多