【问题标题】:Is committing empty transactions expensive?提交空事务是否昂贵?
【发布时间】:2015-10-09 16:03:27
【问题描述】:

在某个 Oracle 11.2 环境中,我观察到不必要的提交,例如

-- some updates/inserts etc.
commit;
select * from mytable where somecond = 23;
commit;

甚至:

update mytable set foo = '42';
commit;
commit;

因此,在这两个示例中,第二次提交都是不必要的,因为事务是“空的” - 没有要提交的内容。

问题是:那些不必要的提交有多昂贵?

Oracle DB 是否“智能”足以检测到此类空事务并用NOPs(无)替换那些不必要的提交?

背景:这些冗余提交有时似乎来自程序员不知道“隐藏”逻辑的某些框架层 - 或者有时它们只是疏忽。根据它们的成本(就数据库性能而言),以高优先级修复代码是有意义的。

【问题讨论】:

  • 取决于您是否认为网络往返速度很慢。
  • 我想知道您是否从正确的方向处理性能问题。
  • @JeffreyKemp,你是什么意思?

标签: oracle oracle11g transactions


【解决方案1】:

空提交并不昂贵,可以忽略。空提交只需要少量 CPU,不会阻塞其他进程或妨碍可扩展性。

正常提交很慢,因为它会导致数据写入磁盘以确保持久性。数据库更改需要 REDO(以防数据库在 数据可以完全写入数据文件,允许恢复向前滚动),UNDO(因此其他事务可以看到更改前的数据), 将新的系统更改号记录到控制文件等中。直到将这些内容写入磁盘后,提交才会完成。

一个空的提交不会做任何这些事情。他们使用 CPU 时间,但可能仅足以检查是否需要进行任何更改。 CPU时间 与写入数据文件、重做日志或控制文件相比,成本更低。它应该可以很好地扩展。

下面的例子表明,真正的问题是在每次微小更改后执行 COMMIT 时。仅运行时间不足以比较这三种方法。 如果您查看 GV$ACTIVE_SESSION_HISTORY 中的等待或磁盘 I/O(来自 Windows 资源监视器、Solaris truss 等),您将看到下面的示例 #1 只使用CPU。示例 #3 使用 CPU、重做日志、数据文件和控制文件。

--#1: Empty commits.
--15 seconds for 1 million commits.
--Only CPU waits, almost no I/O is generated.
begin
    for i in 1..1000000 loop
        commit;
    end loop;
end;
/


--#2: Just inserts.
--34 seconds for 1 million inserts.
--CPU waits, plus some "other" waits.
create table test1(a number);
begin
    for i in 1..1000000 loop
        insert into test1 values(1);
    end loop;
    commit;
end;
/


--#3: Inserts and commits.
--107 seconds for 1 million inserts and commits.
--Lots of CPU waits, lots of "other" waits.
begin
    for i in 1..1000000 loop
        insert into test1 values(1);
        commit;
    end loop;
end;
/

【讨论】:

    【解决方案2】:

    是的,即使没有要提交的内容,也会有开销。发出 COMMIT 时会序列化很多东西,因此会影响可伸缩性。

    HUSQVIK@db> BEGIN
      2     FOR i IN 1..100000 LOOP
      3             NULL;
      4     END LOOP;
      5  END;
      6  /
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:00.00
    HUSQVIK@db> BEGIN
      2     FOR i IN 1..100000 LOOP
      3             COMMIT;
      4     END LOOP;
      5  END;
      6  /
    
    PL/SQL procedure successfully completed.
    
    Elapsed: 00:00:02.37
    

    【讨论】:

      猜你喜欢
      • 2011-04-05
      • 1970-01-01
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多