【问题标题】:Better to commit inside or outside a loop?最好在循环内部还是外部提交?
【发布时间】:2010-10-08 17:25:01
【问题描述】:

也许这个问题没有简单的答案,但如果有人有一个简单的答案,至少我有一个见解。

我曾在很多情况下创建了一个循环,该循环遍历数据库表中的许多记录以执行一些更新,并且我可以在最后合法地进行一次大提交,或者在处理每条记录时提交它.即一次提交一个不会产生任何数据完整性问题。

是否有明确的案例说明哪个更好?

让我想到的是我有一个这样的程序,我最近从一个大提交切换到一堆小提交,因为它是一个运行时间相当长的程序——大约 80 分钟——而且它中途失败了通过不良数据。我解决了问题并重新运行,但是当我本可以让它处理以前未处理的记录时,它不得不从头开始。

当我进行此更改时,我注意到运行时间几乎相同。

【问题讨论】:

    标签: database


    【解决方案1】:

    假设不需要回滚整个持久性的能力(在这种情况下,只有一个答案;在外部提交),在循环内提​​交会使事务日志更小,但需要更多往返数据库。在循环外提交则完全相反。哪个更快取决于平均操作计数和整体提交的数据量。对于保留大约 10-20 条记录的例程,请在循环外提交。对于 1m-2m 的记录,我会分批提交。

    【讨论】:

      【解决方案2】:

      我认为答案是如果一个失败,你是否需要全部回滚?如果是,则将事务放在外面,否则将其放在里面。当然,除了处理相当大批量的记录之外,我几乎从不编写循环来进行更新。如果您正在进行逐行更新,则有更好、性能更高的方法。

      【讨论】:

      • 我不确定您所说的“永远不会编写循环来进行更新,除非处理相当大的批次”。嗯,相对于什么?如果我只有一条记录要更新,我当然不会有循环。
      • 是的,如果必须将整个更新视为单个事务,如果仅完成部分更新会导致数据不一致,那么提交当然必须在外部。我在考虑从逻辑的角度来看没关系的情况。
      • 与基于集合的更新相反。如果您有 100 条记录要更新,它们可以在 99.9% 的时间内在一次更新中完成而没有循环,并且应该这样做。数据库没有针对逐行操作进行优化。
      • 很晚的跟进:如果你的意思是,我可以写一个更新,比如“update my_table set foo=foo*2 where bar=5”,当然,我不会写一百单独的更新语句。当我发布这个问题时,我正在考虑不可能的情况,例如您正在根据来自其他来源的数据进行更新。
      • 当您从其他来源进行更新时,编写基于集合的代码是可能的并且更可取。
      【解决方案3】:

      就性能而言,通常最好在最后进行一次大提交(让网络流量,通常为数据库做更少的工作)。

      这当然取决于很多因素,例如表上的索引、数据量等。

      促使您做出决定的应该是每个更新的重要性 - 它本身是否应该是一个事务?许多项目的更新有意义吗?如果循环中途失败会怎样?

      回答这些问题将为您提供在应用程序中针对该流程执行此操作的正确方法 - 根据应用程序上下文,您可能会采用不同的方式来处理提交。

      【讨论】:

        猜你喜欢
        • 2018-03-17
        • 2021-01-05
        • 1970-01-01
        • 2011-04-10
        • 2015-03-30
        • 2010-09-13
        • 2014-03-24
        • 1970-01-01
        • 2014-03-18
        相关资源
        最近更新 更多