N
N
netW0rm2016-03-13 17:45:30
PostgreSQL
netW0rm, 2016-03-13 17:45:30

How to optimize such a trigger in PostgreSQL?

There is a trigger function

CREATE OR REPLACE FUNCTION update()
RETURNS trigger AS $$
BEGIN
NEW.f1 := some_value();
NEW.updated_at := now(); -- now() будет выполняться на каждой строке?
RETURN NEW;
END;
$$ LANGUAGE plpgsql  VOLATILE

And trigger
CREATE TRIGGER tg_update
BEFORE INSERT OR UPDATE
ON my_table
FOR EACH ROW
EXECUTE PROCEDURE update();

I want to make several optimizations for better performance:
1) the updated_at field should only be updated during the UPDATE operation,
check TG_OP or make an additional trigger or something else, which will be more efficient? It is important here that UPDATE work more efficiently, INSERT is not critical.
2) if the trigger is executed on more rows, will the now() operation be called on each of them? Maybe you can somehow define a variable in which to place the result of now () before calling the trigger? Or somehow through the system of rules to create an additional request, or ...?
To be honest, just yesterday I sat down to read the documentation on triggers and procedural languages ​​and so far I don’t really think)

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
terrier, 2016-03-13
@terrier

check TG_OP or make additional trigger

Yes, in general, this is normal, see how it will be more readable
Yes, in fact, as it is written in the declaration of the trigger "FOR EACH ROW", that is, for each changed row. Well, specifically about now(), I wouldn’t worry too much, this is the time at the beginning of the transaction, it doesn’t change, that is, most likely it just gets a number from the nearby cache. But if there was a long operation instead of now(), you wouldn’t put it in a trigger, right?
However, if it is important for you to set the time once for one SQL query, then you can declare a "FOR EACH STATEMENT" trigger, it will be executed once for each query. But in it, of course, the OLD and NEW tables are not available, that is, some separate query needs time to put down

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question