postgres触发器函数只在另一个表中插入少量记录

时间:2017-07-07 00:18:41

标签: postgresql triggers

我每小时和每天都有2张桌子,我的目标是计算每小时表格的平均值并将其保存到每日表格中。我写了一个像这样的触发函数 -

CREATE OR REPLACE FUNCTION public.calculate_daily_avg()
RETURNS trigger AS
$BODY$
DECLARE chrly CURSOR for
SELECT device, date(datum) datum, avg(cpu_util) cpu_util
FROM chourly WHERE date(datum) = current_date group by device, date(datum);

BEGIN

    FOR chrly_rec IN chrly
    LOOP

    insert into cdaily (device, datum, cpu_util)
    values (chrly_rec.device, chrly_rec.datum, chrly_rec.cpu_util)
        on conflict (device, datum) do update set 
        device=chrly_rec.device, datum=chrly_rec.datum, cpu_util=chrly_rec.cpu_util;

    return NEW;

    END LOOP;
    EXCEPTION
        WHEN NO_DATA_FOUND THEN
        RAISE NOTICE 'NO DATA IN chourly FOR %', current_date;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION public.calculate_daily_avg()
  OWNER TO postgres;

和小时表上的触发器 -

CREATE TRIGGER calculate_daily_avg_trg
  BEFORE INSERT OR UPDATE
  ON public.chourly
  FOR EACH ROW
  EXECUTE PROCEDURE public.calculate_daily_avg();

但是当我尝试在每小时表中插入或更新大约3000条记录时,只插入了3或4个设备,而不是3000.(同样在触发器中我已经尝试过AFTER INSERT或UPDATE,但即使这样也会产生相同的结果)我在这里做错了?如果你觉得我写错了,请建议任何更好的方法来编写触发器。谢谢!

1 个答案:

答案 0 :(得分:0)

我不建议在TRIGGER时使用INSERT进行计算。尝试使用cron每小时或每天执行函数的不同方法。

为什么?

因为每次INSERT一行。 postgres将始终为插入(基于您的流程)执行聚合函数AVG()LOOPING

这意味着另一个INSERT语句将等待Previous INSERT提交,这将使您的数据库性能受到高度INSERT Transaction的影响。如果您以某种方式管理BREAK规则(可能来自配置),您将获得inconsistent数据,就像您现在发生的事情一样。