Sql 在不真正更改数据的情况下发出多个提交时的性能影响

Sql 在不真正更改数据的情况下发出多个提交时的性能影响,sql,performance,oracle,oracle11g,translation,Sql,Performance,Oracle,Oracle11g,Translation,我们有一个访问Oracle11.g底层数据库的系统 作为处理流程的一部分,我们有大约60个进程,每10毫秒轮询数据库以查找要处理的消息 每个处理器在处理器表中都有一个对应的行(处理器ID号、消息编号) 如果为给定的处理器找到要处理的消息,它将更新该处理器的消息ID列。 如果没有要处理的内容,它将用空值更新消息_ID。在我们当前的实现中,即使消息的当前值为null,它仍然会将消息的ID更新为null。用空值更新空值在90%的时间内都会发生 轮询过程发生在容器管理事务(CMT)中 因此,我们有很多假

我们有一个访问Oracle11.g底层数据库的系统

作为处理流程的一部分,我们有大约60个进程,每10毫秒轮询数据库以查找要处理的消息

每个处理器在处理器表中都有一个对应的行(处理器ID号、消息编号)

如果为给定的处理器找到要处理的消息,它将更新该处理器的消息ID列。 如果没有要处理的内容,它将用空值更新消息_ID。在我们当前的实现中,即使消息的当前值为null,它仍然会将消息的ID更新为null。用空值更新空值在90%的时间内都会发生

轮询过程发生在容器管理事务(CMT)中

因此,我们有很多假(null更新为null)更新,然后是提交

60个处理器x 3600秒/小时x 100次更新/秒=2160000次提交/小时

事实上,它们大约是每小时1600万个事务,因为当找到要处理的东西时,在再次寻找工作之前需要更多的时间

理想情况下,如果没有任何变化,我们应该改变我们的系统,不更新处理器条目,我们肯定会这样做。然而,轮询过程的事务性行为不在我们的控制范围内(容器和第三方工作流产品为我们执行此操作),因此无论我们是否更新该记录,仍将有大量提交

因此,我的问题是:您是否认为此“无更新”然后提交将对系统的性能产生影响,如果是,您是否认为删除“无更新”将改善系统的性能

我提出这个问题的原因是,就在发布前几天,作为性能运行的一部分,我们发现系统正常运行了大约十个小时,然后突然不知从哪里开始,它的性能非常差


提前感谢

提交肯定会增加数据库的开销,提交会消耗额外的资源,运行速度较慢。在某些情况下,它还可能导致数据完整性问题

事实上,只有当事务完成时才应该触发提交,而根本没有事务时,为什么还要给数据库增加额外的负担呢

更重要的是,你可以在Tom Kyte的一本书中探索更多。将帮助您更清楚地理解。

删除“不更新”将显著提高性能。将列更新为相同的值与更新为不同的值一样昂贵。下面的简单测试用例显示了在删除不必要的更新后的显著改进

drop table processors;

create table PROCESSORS
(
    PROCESSOR_ID NUMBER primary key,
    MESSAGE_ID NUMBER
);

insert into processors
select level, null
from dual connect by level <= 100;

commit;

begin
    for i in 1 .. 100000 loop
        update processors set message_id = null where processor_id = 1;
        commit;
    end loop;
end;
/

begin
    for i in 1 .. 100000 loop
        --update processors set message_id = null where processor_id = 1;
        commit;
    end loop;
end;
/
drop表处理器;
创建表处理器
(
处理器ID号主键,
消息标识号
);
插入到处理器中
选择级别,空

从dual connect by level开始,我本以为Oracle会足够聪明,当我用相同的值更新给定字段时,记录(或数据块)根本不会改变(通过在数据上应用一些非常快速的MD5算法,并实现没有任何更改,甚至不用麻烦将该块标记为脏块并创建重做日志条目以进行“假更新”。看起来我的假设是错误的,所以我别无选择,只能避免重复更新。嗯……我的老板不会对发布延迟感到满意,但我打赌延迟发布比紧急发布更重要。使用MD5算法会有额外的成本,此外它不安全,还可能出现误报。此外,为什么不修改update语句以确保值实际发生更改?