2015-10-09 141 views
2

在某个Oracle 11.2环境中,我观察到不必要的提交,例如是否承诺空交易昂贵?

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

甚至:

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

因此,在这两个例子中的第二个承诺是不必要的,因为交易是“空” - 没有什么承诺。

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

是否Oracle数据库'智能'足以检测这种空的事务并用NOPs(无)替代那些不必要的提交?

背景:这些冗余提交有时似乎来自特定框架层,程序员没有意识到“隐藏”逻辑 - 或者有时他们只是疏忽。根据数据库的性价比(根据数据库性能),以高优先级修复代码是有意义的。

+1

取决于您是否考虑网络往返速度慢或不慢。 – eckes

+0

我想知道您是否从正确的方向接近性能问题。 –

+0

@JeffreyKemp,你是什么意思? – maxschlepzig

回答

2

空提交并不昂贵,可以忽略。空提交只需要少量的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时有很多事情需要序列化,因此可伸缩性会受到影响。

[email protected]> 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 
[email protected]> 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