【问题标题】:Is ROLLBACK TO SAVEPOINT better performing than ROLLBACK TRANSACTION?ROLLBACK TO SAVEPOINT 是否比 ROLLBACK TRANSACTION 性能更好?
【发布时间】:2020-03-05 09:19:41
【问题描述】:

我有一个脚本,它根据从文件中读取的数据,对一个中等大小(大约 600 万行)的表执行一系列更新。

它当前开始,然后为它更新的每一行提交一个事务,我想以某种方式提高它的性能。我想知道在脚本运行开始时启动单个事务然后回滚到单个保存点以防发生任何验证错误实际上会导致性能提高。

我上网查了一下,但没有找到任何文档或基准。

【问题讨论】:

  • 你在那里处理什么样的错误?也许使用insert on conflict 会是一个更好的解决方案,这样您就不会首先遇到错误。但是没有看到代码,这很难回答。
  • 由于您提交了每一行,如果您的脚本在中途失败(例如,停电),您将如何确定从哪里重新开始?答案决定了您拥有的选择范围。

标签: postgresql postgresql-11


【解决方案1】:

COMMIT 主要是 I/O 问题,因为事务日志 (WAL) 必须同步到磁盘。

因此,使用子事务(保存点)很可能会提高性能。但请注意,如果您有并发事务,则每个事务使用超过 64 个子事务将再次损害性能。

如果您可以忍受在数据库服务器崩溃时丢失一些已提交的事务(这种情况很少见),您可以简单地将 synchronous_commit 设置为 off 并坚持许多小事务。

另一种更复杂的方法是分批处理行而不使用子事务并在出现问题时重复整个批处理。

【讨论】:

    【解决方案2】:

    拥有一个只有 1 个 COMMIT 的事务应该比拥有多个单行更新事务更快,因为每个 COMMIT 必须同步 WAL 写入磁盘。但是在给定环境中它的真正速度取决于很多环境(事务数量、表结构、索引结构、UPDATE 语句、PostgreSQL 配置、系统配置等):只有您可以在您的环境中进行基准测试。

    【讨论】:

    • 感谢您的回答。不幸的是,在我的情况下,在输入文件中回滚整个事务中的单个错误实际上并不可行。 :(
    猜你喜欢
    • 2020-04-13
    • 2016-01-05
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2017-01-20
    • 2013-01-23
    相关资源
    最近更新 更多