Триггеры 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;