【问题标题】:Deleting in bunch - autocommit vs begin/commit transaction批量删除 - 自动提交与开始/提交事务
【发布时间】:2015-12-28 10:24:20
【问题描述】:

我在解决数据库中的问题时遇到了问题。我试图寻找答案,但我发现了两个模棱两可的解决方案。

问题: 在删除大量数据期间,我收到错误消息:“数据库 '[TableName]' 的事务日志已满。”有人建议我删除部分数据。

我发现了两种不同的方法来解决这个问题:

1)

DECLARE @Count INT
Declare @for_delete INT
Declare @chunk_size INT
SELECT @chunk_size=100000
SELECT @Count = 0
select @for_delete=count(*) from [Your big table] where  [Your Where Clause]
While (@Count < @for_delete)
BEGIN
SELECT @Count = @Count + @chunk_size
BEGIN TRAN
DELETE top(@chunk_size) FROM  [Your big table] where  [Your Where Clause]
COMMIT TRAN
END

2)

WHILE EXISTS(SELECT TOP 1 1 FROM Table)
BEGIN
DELETE TOP (10000) FROM Table
END

我的问题是,为什么在第一个示例中,单个操作有一个 Begin/Commit tran (Delete Top(x)....)?我认为单个操作是自动提交 - 因此不需要开始/提交? 您能否解释一下哪个选项最适合避免有关完整事务日志的错误? Begin/Commit tran 对于单个操作是必需的吗? 非常感谢您的帮助。

【问题讨论】:

  • 这是您只需要一次,还是您需要更频繁,还是作为某些业务流程的一部分?
  • 这是业务流程的一部分。我需要调整所有程序(负责删除数据)以部分删除数据。
  • 当用户在表中工作时这些删除是否会运行,或者这会是一种“夜间清理”吗?
  • 不时执行删除(每周一次 - 但在正常工作时间)。用户只使用 SELECT 类型的查询。
  • 您选择了哪种恢复配置文件,您是否定期备份数据库,包括事务日志?

标签: sql-server autocommit


【解决方案1】:

可能不需要打开和关闭事务,但这是很好的做法。

由于这两种方法都在一个大作业中运行,因此在作业结束之前不会关闭隐式事务。

您可以尝试在其自己的作业中运行每个删除部分。在 SQL Server Management Studio 中,可以使用带有 INT 参数的“GO”:阅读此处:https://stackoverflow.com/a/3092835/5089204

通过这个非常有用的技巧,您可以删除块并在每轮运行DBCC SHRINKFILE(N'YourLogFile',0,TRUNCATEONLY)

【讨论】:

  • 非常感谢Shnugo!
猜你喜欢
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
相关资源
最近更新 更多