Luk*_*der 6 oracle performance triggers oracle11g
我们的大多数表都有一个BEFORE INSERT OR UPDATE触发器,以便设置ID BEFORE INSERT并设置创建/修改用户/日期BEFORE INSERT OR UPDATE.
有几个表带有额外的触发器,它们与前一个触发器分开,以使其意图更加清晰.此外,这些附加触发器可以独立于前一个触发器禁用,永远不应禁用.
在大多数情况下,附加触发器也会触发BEFORE INSERT OR UPDATE,并且顺序不重要,因为它们涵盖了不同的列/用例.通常,它们可以组合成单个触发器.
关于桌子上的呼叫1或n触发器的速度是否有任何研究?或者这与单行插入/更新几乎无关?换句话说,是否只有1个全局SQL -> PL/SQL上下文切换,或者每个触发器将有1个上下文切换.
我现在已经对这种情况进行了基准测试,我得出的结论是,当添加1个触发器时,由于PL/SQL上下文切换,很可能会出现严重的性能损失.在我的基准测试中,损失是因子8.然而,添加第二个"兼容"触发器不再具有任何重大影响.通过"兼容",我的意思是两个触发器总是以任何顺序在同一事件中触发.
所以我得出结论,SQL -> PL/SQL所有触发器最有可能只有1个上下文切换
这是基准:
-- A typical table with primary key, creation/modification user/date, and
-- other data columns
CREATE TABLE test(
id number(38) not null, -- pk
uc varchar2(400) not null, -- creation user
dc date not null, -- creation date
um varchar2(400), -- modification user
dm date, -- modification date
data number(38)
);
Run Code Online (Sandbox Code Playgroud)
CREATE SEQUENCE s_test;
Run Code Online (Sandbox Code Playgroud)
CREATE OR REPLACE TRIGGER t_test BEFORE INSERT OR UPDATE
ON test
FOR EACH ROW
BEGIN
IF inserting THEN
SELECT s_test.nextval INTO :new.id FROM dual;
:new.uc := USER;
:new.dc := SYSDATE;
:new.um := NULL;
:new.dm := NULL;
END IF;
IF updating THEN
:new.um := USER;
:new.dm := SYSDATE;
:new.uc := :old.uc;
:new.dc := :old.dc;
END IF;
END t_test;
Run Code Online (Sandbox Code Playgroud)
declare
procedure run (limit number) is
t timestamp;
begin
t := systimestamp;
insert into test (data)
select level from dual connect by level < limit;
dbms_output.put_line(to_char(systimestamp - t));
rollback;
end;
begin
run(1000);
run(10000);
run(100000);
end;
Run Code Online (Sandbox Code Playgroud)
-- ------------------------------------
-- +000000000 00:00:00.086603000
-- +000000000 00:00:00.844333000
-- +000000000 00:00:08.429186000
-- ------------------------------------
Run Code Online (Sandbox Code Playgroud)
CREATE OR REPLACE TRIGGER t_test_other BEFORE INSERT OR UPDATE
ON test
FOR EACH ROW
BEGIN
:new.data := 42;
END t_test_other;
Run Code Online (Sandbox Code Playgroud)
-- ------------------------------------
-- +000000000 00:00:00.088551000
-- +000000000 00:00:00.876028000
-- +000000000 00:00:08.731345000
-- ------------------------------------
Run Code Online (Sandbox Code Playgroud)
alter trigger t_test disable;
alter trigger t_test_other disable;
Run Code Online (Sandbox Code Playgroud)
declare
procedure run (limit number) is
t timestamp;
begin
t := systimestamp;
insert into test (id, uc, dc, data)
select s_test.nextval, user, sysdate, level from dual
connect by level < limit;
dbms_output.put_line(to_char(systimestamp - t));
rollback;
end;
begin
run(1000);
run(10000);
run(100000);
end;
Run Code Online (Sandbox Code Playgroud)
-- ------------------------------------
-- +000000000 00:00:00.012712000
-- +000000000 00:00:00.104903000
-- +000000000 00:00:01.043984000
-- ------------------------------------
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2140 次 |
| 最近记录: |