Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance PostgreSQL-前触发器是否比后触发器更有效?_Performance_Postgresql_Triggers - Fatal编程技术网

Performance PostgreSQL-前触发器是否比后触发器更有效?

Performance PostgreSQL-前触发器是否比后触发器更有效?,performance,postgresql,triggers,Performance,Postgresql,Triggers,我刚刚在文章中读到,前触发比后触发“更有效”: 如果你没有具体的理由 触发器之前或之后,之前 由于 有关行动的资料 不必保存到 声明 我不明白这是真的还是对我意味着什么。有人能启发我吗?这仅仅是一种顺势疗法的性能改进吗?要想证明这一点,唯一的方法就是测试它,看看它是否对你的工作有影响 高层次的逻辑思考。。。如果你正在采取额外的步骤来保留更多的信息,与不采取额外的步骤相比,当然一个步骤比另一个步骤要多。正如多走一步是一项更大的工作,即使它可能不需要你一个明显的时间差。例如,用10步走10英尺,而不

我刚刚在文章中读到,前触发比后触发“更有效”:

如果你没有具体的理由 触发器之前或之后,之前 由于 有关行动的资料 不必保存到 声明


我不明白这是真的还是对我意味着什么。有人能启发我吗?这仅仅是一种顺势疗法的性能改进吗?

要想证明这一点,唯一的方法就是测试它,看看它是否对你的工作有影响


高层次的逻辑思考。。。如果你正在采取额外的步骤来保留更多的信息,与不采取额外的步骤相比,当然一个步骤比另一个步骤要多。正如多走一步是一项更大的工作,即使它可能不需要你一个明显的时间差。例如,用10步走10英尺,而不是11步走。

对于更新触发器,我发现我的系统没有可测量的差异:

使用“before”触发器:

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;
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
使用“after”触发器:

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;
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

但由于某种原因,与“后”插入触发器或控件相比,“前”插入触发器的性能下降非常明显

由于
PostgreSQL
MVCC
体系结构,每次操作都会增加系统中记录的数据量,甚至
DELETE


因此,如果您只需要检查输入并在检查失败时回滚事务,最好在保存输入数据之前进行检查。

+1感谢您的尝试。“但是你的结果真的没有显示AFTER速度慢吗?”丹尼尔将每个测试与一个对照组进行比较。(相同)控件之间的差异幅度远远大于控件和
update
之间的差异,在每种情况下都有一个触发器当Postgres在行之间的
触发器之前激发
时,它在
触发器之后直到语句结束才开始激发
。换句话说,
AFTER
触发器都不在您的
时间范围内。您最好只使用psql的
\time
+1这对我来说更容易理解。如果只是错误情况无关紧要,我将不再关心这种速度差异。删除不会增加系统中记录的数据量,它只是不会释放没有真空的空间。这就是autovacuum所做的,它清理死元组。@Frank:它确实增加了
WAL
,这就是为什么我写的是“系统”而不是“表空间”。@Frank我认为Quassnoi的观点是,在提交之前,越早按照MVCC的意思执行事务,回滚事务的效率就越高,已删除的行对其他所有人仍然可见。这肯定是一个很好的观点。如果我更新触发器中某个相关表中的记录会怎么样。以前使用它更好吗?例如,我在INSERT上有触发器,希望在我自己的统计表中增加计数器。触发前是否仍然有效和合适?