【问题标题】:Update Zero Rows and then Committing?更新零行然后提交?
【发布时间】:2011-04-10 23:36:54
【问题描述】:

对于影响零行的更新,哪个过程的性能更高?

UPDATE table SET column = value WHERE id = number;

IF SQL%Rowcount > 0 THEN
 COMMIT;
END IF;

UPDATE table SET column = value WHERE id = number;

COMMIT;

换句话说,如果更新影响零行并且发出提交,我是否会产生任何额外费用?

我的系统受到日志文件同步等待的阻碍...我想知道是否发出提交;反对影响零行的事务会将该语句写入日志或不写入日志,从而导致更多的 LGWR 争用。

【问题讨论】:

    标签: sql oracle commit


    【解决方案1】:

    COMMIT 确实会强制同步日志文件,因此系统确实需要等待。

    但是,ROLLBACK 也有,而且在某些时候它们中的任何一个都必须发生。

    因此,如果您既没有发出 COMMIT 也没有发出 ROLLBACK,那么您只是停留在一个打开的事务中,迟早导致日志同步等待。

    您可能希望批量处理UPDATE 操作,而不是等待第一次成功更新并提交。

    【讨论】:

    • 如果更新不影响任何行,我认为它不会打开事务。不影响行的更新不会显示在 v$transaction 中(尽管可能还有更多内容?)我认为这意味着不需要提交或回滚。从一些简单的测试看来,避免提交的速度大约是原来的两倍。但无论哪种方式,执行数万次此类操作的时间都不到一秒。 (尽管当有其他会话做大量工作时,无意义的提交可能会变得更加昂贵?)
    • @jonearles:是的,它确实打开了交易并且确实显示在v$transaction
    • 虽然 dbms_transaction.local_transaction_id() 返回一个非空值,但它并没有出现在 10.2.0.1.0 (XE) 上的 v$transaction 中。根据文档,他们都应该显示活动交易。这是我的命令和结果,您对 v$transaction 有什么不同吗? (不包括其他会话) create table update_test(id number, test1 varchar2(100)); [表已创建。] update update_test set test1 = 'asdf' where id = 12345; [0 行更新。] 从 v$transaction 中选择 count(*); [0] 从对偶中选择 dbms_transaction.local_transaction_id(); [10.35.8322]
    • @jonearles:我在v$transaction也看到了一条记录。
    • 所以每个 DML 语句都会打开一个必须通过提交或回滚关闭的事务。从不返回任何行的选择中插入或使用不删除/更改任何行的 where 子句进行删除或更新都需要最终提交或更新。在大多数情况下,我告诉人们永远不要先检查,让数据库告诉你...... i.o.w.不要在插入之前检查您是否会破坏 PK,只需为那些这样做的人捕获错误。在这些情况下,情况正好相反...检查您的更新是否会影响行,因为如果没有,您将打开一个不必要的事务。
    【解决方案2】:

    这有风险。从技术上讲,虽然 UPDATE 可能会影响零行,但它可以在表上的更新触发器之前或之后触发(而不是在行级别)。这些触发器可能会“做某事”,需要提交/回滚。

    检查是否设置了LOCAL_TRANSACTION_ID 更安全。

    【讨论】:

    • 这是正确的好建议,尽管它不能回答问题。我赞成它的建议,但给出了问题的实际“答案”的答案。
    【解决方案3】:

    等待log file sync 的原因有很多。罪魁祸首似乎不太可能是提交已更新零行的 SQL 语句。确实,发出太多提交可能是导致此问题的原因。例如,如果应用程序设置为在每个语句之后提交(例如,通过使用 AUTOCOMMIT=TRUE)而不是设计正确的事务。如果这是原因,那么除了对应用程序进行重大重写之外,您无能为力。

    如果您想深入了解问题的根本原因,我建议您阅读 Pythian 的 Riyaj Shamsudeen 在Tuning ‘log file sync’ Event Waits 撰写的这篇详尽(且令人精疲力竭)的文章。

    【讨论】:

    • 我从来没有说过,“罪魁祸首是提交已更新零行的 SQL 语句”。不过,这将是我的解决方案。 “应用程序的重大重写”的替代简称。
    • 这并不试图回答这个问题。你是在猜测问题所在。
    • @StephaniePage - 实际上我故意没有试图猜测问题。我认为您的问题实际上是关于 LOG FILE SYNC 等待的原因,但显然我错了。我的错。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2012-12-12
    • 2013-10-15
    相关资源
    最近更新 更多