我在oracle触发器中有关于OF,IF和WHEN子句性能的查询。请考虑以下触发器-
CREATE OR REPLACE TRIGGER WeightChange
AFTER UPDATE ON Person
FOR EACH ROW
BEGIN
IF :new.Weight > 250 AND new:Weight > old:Weight THEN
LogWeightChange(:new.PersonId, :new.Weight, :old.Weight);
END IF;
END WeightChange;
现在,如果我进行以下更改,
以上任何一项或全部内容是否会大大改善触发条件?
答案 0 :(得分:1)
WHEN (condition)
和OF column
触发功能可以显着提高触发性能。触发器的大部分性能损失是SQL和PL / SQL上下文切换,通过将更多的逻辑转移到SQL中,可以避免这些切换。
例如,让我们从一个简单的模式开始:
--Sample schema with 100K simple PERSON rows.
create table person
(
id number not null primary key,
name varchar2(100),
weight number
);
insert into person
select level, level, 100 from dual connect by level <= 100000;
commit;
启用或禁用不同的触发功能:
--Create trigger that fires for all rows.
CREATE OR REPLACE TRIGGER WeightChange
AFTER UPDATE ON Person
FOR EACH ROW
BEGIN
IF :new.Weight > 250 AND :new.Weight > :old.Weight THEN
null;
END IF;
END WeightChange;
/
--Create trigger that only fires for relevant rows.
CREATE OR REPLACE TRIGGER WeightChange
AFTER UPDATE ON Person
FOR EACH ROW
WHEN (new.Weight > 250 AND new.Weight > old.Weight)
BEGIN
null;
END WeightChange;
/
--Create trigger that fires for all updates of WEIGHT.
CREATE OR REPLACE TRIGGER WeightChange
AFTER UPDATE OF weight ON person
FOR EACH ROW
WHEN (new.Weight > 250 AND new.Weight > old.Weight)
BEGIN
null;
END WeightChange;
/
--No trigger.
drop trigger WeightChange;
WHEN (condition)
和OF column
功能可以使UPDATE
语句在最佳情况下的运行速度几乎快一倍。
--With no trigger - FAST:
--0.749, 0.670, 0.733
update person set weight = 100;
rollback;
--With normal trigger - SLOW:
--1.295, 1.279, 1.264 seconds
update person set weight = 100;
rollback;
--With WHEN condition trigger - FAST:
--0.687, 0.686, 0.687
update person set weight = 100;
rollback;
--With WHEN condition, using a value that satisfies conditions - SLOW:
--1.233, 1.232, 1.233
update person set weight = 500;
rollback;
--With normal trigger, update irrelevant column - SLOW:
--1.263, 1.248, 1.248
update person set name = name;
rollback;
--With OF column trigger, update irrelevant column - FAST:
--0.624, 0.624, 0.609
update person set name = name;
rollback;