performance - instead - triggers sql
PostgreSQL: ¿ANTES los desencadenadores son más eficientes que los disparadores DESPUÉS? (3)
Acabo de leer en la documentación de PostgreSQL - Descripción general del comportamiento del disparador , que ANTES de los desencadenadores es "más eficiente" que los desencadenadores DESPUÉS:
Si no tiene un motivo específico para activar un desencadenante antes o después, el caso anterior es más eficiente, ya que la información sobre la operación no tiene que guardarse hasta el final de la instrucción.
No entiendo si esto es cierto o lo que significa para mí. ¿Alguien me puede iluminar? ¿Es solo una mejora en el rendimiento homeopático?
La única forma en que lo probarás de una manera u otra es probarlo y ver si importa lo que estás haciendo.
Pensando lógicamente en el alto nivel ... si está dando un paso más para retener más información, sin tomar el paso adicional, por supuesto, uno es más trabajo que el otro. De la misma manera que caminar un paso más es más trabajo, aunque no le tome una diferencia de tiempo notable. Por ejemplo, caminar 10 pies con 10 pasos frente a 11 pasos.
Para un activador de actualización, no encontré ninguna diferencia medible en mi sistema:
con el disparador ''antes'':
begin;
create function f() returns trigger language plpgsql as $$
begin
new.time_of_day:=old.time_of_day+''1d''::interval;
return new;
end;$$;
create table t(time_of_day timestamp);
insert into t(time_of_day)
select timeofday()::timestamp from generate_series(1,100000);
update t set time_of_day = timeofday()::timestamp;
select max(time_of_day)-min(time_of_day) from t;
?column?
-----------------
00:00:47
create trigger trig before insert on t for each row execute procedure f();
update t set time_of_day = timeofday()::timestamp;
select max(time_of_day)-min(time_of_day) from t;
?column?
-----------------
00:00:47.432173
rollback;
con el disparador ''después'':
create function f() returns trigger language plpgsql as $$
begin
new.time_of_day:=old.time_of_day+''1d''::interval;
return new;
end;$$;
create table t(time_of_day timestamp);
insert into t(time_of_day)
select timeofday()::timestamp from generate_series(1,100000);
update t set time_of_day = timeofday()::timestamp;
select max(time_of_day)-min(time_of_day) from t;
?column?
-----------------
00:00:48.566558
create trigger trig after insert on t for each row execute procedure f();
update t set time_of_day = timeofday()::timestamp;
select max(time_of_day)-min(time_of_day) from t;
?column?
-----------------
00:00:48.922441
Pero por alguna razón tengo una degradación muy notable con un disparador de inserción "anterior" en comparación con un disparador de inserción "posterior" o un control
Debido a la arquitectura MVCC
PostgreSQL
, cada operación aumenta la cantidad de datos grabados en el sistema, incluso DELETE
.
Entonces, si solo necesita hacer comprobaciones de su entrada y deshacer la transacción si las comprobaciones fallan, será mejor que lo haga antes de que se guarden los datos de entrada.