Thread: Update on tables when the row doesn't change

Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Hi all,

maybe it's a very silly question, but why does Postgres perform an
update on the table even if no data changes?

I recognized this recently doing a rewrite of my rules because they
took to long. I had many conditional rules I collapsed to one
unconditional rule, so that the views get constructed only once. If I
split these updates to the underlying tables, I get a lot of updates
which don't perform any "real" updates.

Can I circumvent this behaviour of Postgres only by defining lot of
rules / triggers on these underlying table are there some trickier ways?

Any help appreciated,

Sebastian

Re: Update on tables when the row doesn't change

From
Martijn van Oosterhout
Date:
I'm sure I'm not the only one, but, what are you talking about? RULEs
are not really obvious so it would help if you could post an example of
what you mean...

Have a nice day,

On Tue, May 24, 2005 at 05:05:34PM +0200, Sebastian Böck wrote:
> Hi all,
>
> maybe it's a very silly question, but why does Postgres perform an
> update on the table even if no data changes?
>
> I recognized this recently doing a rewrite of my rules because they
> took to long. I had many conditional rules I collapsed to one
> unconditional rule, so that the views get constructed only once. If I
> split these updates to the underlying tables, I get a lot of updates
> which don't perform any "real" updates.
>
> Can I circumvent this behaviour of Postgres only by defining lot of
> rules / triggers on these underlying table are there some trickier ways?
>
> Any help appreciated,
>
> Sebastian
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: if posting/reading through Usenet, please send an appropriate
>      subscribe-nomail command to majordomo@postgresql.org so that your
>      message can get through to the mailing list cleanly

--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Attachment

Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Martijn van Oosterhout wrote:
> I'm sure I'm not the only one, but, what are you talking about? RULEs
> are not really obvious so it would help if you could post an example of
> what you mean...
>
> Have a nice day,

Hi, I'm not really talking about rules.

I'm talking about updates on *real* tables, and how to avoid
unnecessary updates on these tables if the row doesn't change.

The situation looks like this:

I have a view which is a join of a lot of tables.

I have lot of conditional ON UPDATE rules to that view that split one
update to the view into updates on the underlying table. The condition
of each rule is constructed in a way that the underlying table only
gets an update if the corresponding values change.

If I collapse all these rules into one conditional rule and pass all
the updates to the underlying tables, I get a lot of unnecessary
updates to these real tables, if the values don't change.

Thats what I want to avoid.

Sorry for not beeing that clear.

Sebastian



Re: Update on tables when the row doesn't change

From
Jaime Casanova
Date:
On 5/24/05, Sebastian Böck <sebastianboeck@freenet.de> wrote:
> Martijn van Oosterhout wrote:
> > I'm sure I'm not the only one, but, what are you talking about? RULEs
> > are not really obvious so it would help if you could post an example of
> > what you mean...
> >
> > Have a nice day,
>
> Hi, I'm not really talking about rules.
>
> I'm talking about updates on *real* tables, and how to avoid
> unnecessary updates on these tables if the row doesn't change.
>
> The situation looks like this:
>
> I have a view which is a join of a lot of tables.
>
> I have lot of conditional ON UPDATE rules to that view that split one
> update to the view into updates on the underlying table. The condition
> of each rule is constructed in a way that the underlying table only
> gets an update if the corresponding values change.
>
> If I collapse all these rules into one conditional rule and pass all
> the updates to the underlying tables, I get a lot of unnecessary
> updates to these real tables, if the values don't change.
>
> Thats what I want to avoid.
>
> Sorry for not beeing that clear.
>
> Sebastian
>
>
And how are you preventing the rule execute the update if the field
has no change? That is way Martijn told you about showing the rule.

AFAIK, if you execute an update on a view that has a ON UPDATE rule
all the SQL ACTIONS specified for the rule will be perfomed INSTEAD OF
the original update


--
Atentamente,
Jaime Casanova
(DBA: DataBase Aniquilator ;)

Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Jaime Casanova wrote:
> On 5/24/05, Sebastian Böck <sebastianboeck@freenet.de> wrote:
>
>>Martijn van Oosterhout wrote:
>>
>>>I'm sure I'm not the only one, but, what are you talking about? RULEs
>>>are not really obvious so it would help if you could post an example of
>>>what you mean...

I attach some sample SQL (commented) to demonstrate the described
scenario:

>>Hi, I'm not really talking about rules.
>>
>>I'm talking about updates on *real* tables, and how to avoid
>>unnecessary updates on these tables if the row doesn't change.
>>
>>The situation looks like this:
>>
>>I have a view which is a join of a lot of tables.
>>
>>I have lot of conditional ON UPDATE rules to that view that split one
>>update to the view into updates on the underlying table. The condition
>>of each rule is constructed in a way that the underlying table only
>>gets an update if the corresponding values change.
>>
>>If I collapse all these rules into one conditional rule and pass all
>>the updates to the underlying tables, I get a lot of unnecessary
>>updates to these real tables, if the values don't change.
>>
>>Thats what I want to avoid.
>>
>>Sorry for not beeing that clear.
>>
>>Sebastian
>>
>>
>
> And how are you preventing the rule execute the update if the field
> has no change? That is way Martijn told you about showing the rule.

Sorry I don't understand what you mean.
What's wrong with:

CREATE OR REPLACE RULE upd AS ON UPDATE TO view
WHERE NEW.field = OLD.field DO INSTEAD NOTHING;

> AFAIK, if you execute an update on a view that has a ON UPDATE rule
> all the SQL ACTIONS specified for the rule will be perfomed INSTEAD OF
> the original update

Ok thanks for the tip, but I alredy knew this ;)

But my original question remeins:

Why does Postgres perform updates to tables, even if the row doesn't
change at all?

Thanks

Sebastian



Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Sorry, missed the SQL to test.

Sebastian

/* tables */
CREATE TABLE test (
    id INTEGER PRIMARY KEY,
    test TEXT NOT NULL
);

CREATE TABLE join1 (
    id INTEGER PRIMARY KEY,
    text1 TEXT NOT NULL
);

CREATE TABLE join2 (
    id INTEGER PRIMARY KEY,
    text2 TEXT NOT NULL
);

CREATE TABLE join3 (
    id INTEGER PRIMARY KEY,
    text3 TEXT NOT NULL
);

/* view */
CREATE OR REPLACE VIEW view_test AS
    SELECT
        id,
        test,
        text1,
        text2,
        text3
    FROM test
    LEFT JOIN join1 USING (id)
    LEFT JOIN join2 USING (id)
    LEFT JOIN join3 USING (id);

/* data */
INSERT INTO test (id) VALUES ('1','Test 1');
INSERT INTO test (id) VALUES ('2','Test 2');
INSERT INTO test (id) VALUES ('3','Test 3');

INSERT INTO join1 (id,text1) VALUES ('1','Test 1 1');
INSERT INTO join1 (id,text1) VALUES ('2','Test 1 2');
INSERT INTO join1 (id,text1) VALUES ('3','Test 1 3');

INSERT INTO join2 (id,text2) VALUES ('1','Test 2 1');
INSERT INTO join2 (id,text2) VALUES ('2','Test 2 2');
INSERT INTO join2 (id,text2) VALUES ('3','Test 2 3');

INSERT INTO join3 (id,text3) VALUES ('1','Test 3 1');
INSERT INTO join3 (id,text3) VALUES ('2','Test 3 2');
INSERT INTO join3 (id,text3) VALUES ('3','Test 3 3');

/* 1st way of separating updates
   pro: no unnecessary updates on tables
   con: the view gets evaluated 4 times

This was the whole thing being before change.
This can get *really* slow, if the view itself is not the fastest.

*/
CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
    DO INSTEAD NOTHING;
CREATE OR REPLACE RULE upd_ AS ON UPDATE TO view_test
    WHERE NEW.test <> OLD.test
    DO UPDATE test
    SET test = NEW.test
    WHERE id = OLD.id;
CREATE OR REPLACE RULE upd_1 AS ON UPDATE TO view_test
    WHERE NEW.text1 <> OLD.text1
    DO UPDATE join1
    SET text1 = NEW.text1
    WHERE id = OLD.id;
CREATE OR REPLACE RULE upd_2 AS ON UPDATE TO view_test
    WHERE NEW.text2 <> OLD.text2
    DO UPDATE join2
    SET text2 = NEW.text2
    WHERE id = OLD.id;
CREATE OR REPLACE RULE upd_3 AS ON UPDATE TO view_test
    WHERE NEW.text3 <> OLD.text3
    DO UPDATE join3
    SET text3 = NEW.text3
    WHERE id = OLD.id;

/* 2nd way of separating updates
   pro: ?
   con: the view gets evaluated 4 times, why?
        unnecessary updates on tables

   First approach to reduce execution time of update, but view gets
   also evaluated 4 times (no performance boost).
   Here I discovered the problem that all underlying tables are getting
   the updates, even if the data in that table doesn't change.
   This can hurt you as well, if you log all updates.

*/

DROP RULE upd_ ON view_test;
DROP RULE upd_1 ON view_test;
DROP RULE upd_2 ON view_test;
DROP RULE upd_3 ON view_test;

CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
    DO INSTEAD (
        UPDATE test SET test = NEW.test WHERE id = OLD.id;
        UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
        UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
        UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
    );

/* 3rd way of separating updates
   con: unnecessary updates on tables
   pro: view gets evaluated only 1 time

   Not adressing the problem of unnecessary updates, but the view
   gets only evaluated one time.

*/

CREATE OR REPLACE FUNCTION upd (view_test) RETURNS VOID AS $$
    DECLARE
        NEW ALIAS FOR $1;
    BEGIN
        RAISE NOTICE 'UPDATE';
        UPDATE test SET test = NEW.test WHERE id = OLD.id;
        UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
        UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
        UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
        RETURN;
    END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
    DO INSTEAD SELECT upd (NEW.*);

/* 4th way of doing it
   pro: view gets evaluated only 1 time
        no unnecessary updates on tables
   con: ??

   Here is the way I solved all my performance problems.
   Only remainig issue: How can I eliminate the response of the select?

*/

CREATE OR REPLACE FUNCTION upd (view_test, view_test) RETURNS VOID AS $$
    DECLARE
        NEW ALIAS FOR $1;
        OLD ALIAS FOR $2;
    BEGIN
        IF (NEW.test <> OLD.test) THEN
            RAISE NOTICE 'UPDATE test';
            UPDATE test SET test = NEW.test WHERE id = OLD.id;
        END IF;
        IF (NEW.text1 <> OLD.text1) THEN
            RAISE NOTICE 'UPDATE join1';
            UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
        END IF;
        IF (NEW.text2 <> OLD.text2) THEN
            RAISE NOTICE 'UPDATE join2';
            UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
        END IF;
        IF (NEW.text3 <> OLD.text3) THEN
            RAISE NOTICE 'UPDATE join3';
            UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
        END IF;
        RETURN;
    END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
    DO INSTEAD SELECT upd (NEW.*,OLD.*);


Re: Update on tables when the row doesn't change

From
Tom Lane
Date:
=?ISO-8859-1?Q?Sebastian_B=F6ck?= <sebastianboeck@freenet.de> writes:
> Why does Postgres perform updates to tables, even if the row doesn't
> change at all?

Because testing for this would almost surely be a net loss for the vast
majority of applications.  Checking to see if the new row value exactly
equals the old is hardly a zero-cost operation; if you pay that on every
update, that's a lot of overhead that you are hoping to make back by
sometimes avoiding the physical store of the new tuple.  In most
applications I think the "sometimes" isn't going to be often enough
to justify doing it.

If you have a particular table in a particular app where it is worth it,
I'd recommend writing a BEFORE UPDATE trigger to make the comparisons
and suppress the update when NEW and OLD are equal.

            regards, tom lane

Re: Update on tables when the row doesn't change

From
Richard Huxton
Date:
Tom Lane wrote:
> =?ISO-8859-1?Q?Sebastian_B=F6ck?= <sebastianboeck@freenet.de> writes:
>
>>Why does Postgres perform updates to tables, even if the row doesn't
>>change at all?
>
>
> Because testing for this would almost surely be a net loss for the vast
> majority of applications.  Checking to see if the new row value exactly
> equals the old is hardly a zero-cost operation; if you pay that on every
> update, that's a lot of overhead that you are hoping to make back by
> sometimes avoiding the physical store of the new tuple.  In most
> applications I think the "sometimes" isn't going to be often enough
> to justify doing it.
>
> If you have a particular table in a particular app where it is worth it,
> I'd recommend writing a BEFORE UPDATE trigger to make the comparisons
> and suppress the update when NEW and OLD are equal.

In any case, what if I have a trigger that's supposed to increment a
counter or similar if issue a supposedly "unneeded" update.

--
   Richard Huxton
   Archonet Ltd

Re: Update on tables when the row doesn't change

From
Dawid Kuroczko
Date:
On 5/24/05, Sebastian Böck <sebastianboeck@freenet.de> wrote:
> /* 3rd way of separating updates
>    con: unnecessary updates on tables
>    pro: view gets evaluated only 1 time
>
>    Not adressing the problem of unnecessary updates, but the view
>    gets only evaluated one time.
>
> */
>
> CREATE OR REPLACE FUNCTION upd (view_test) RETURNS VOID AS $$
>         DECLARE
>                 NEW ALIAS FOR $1;
>         BEGIN
>                 RAISE NOTICE 'UPDATE';
>                 UPDATE test SET test = NEW.test WHERE id = OLD.id;
>                 UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
>                 UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
>                 UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
>                 RETURN;
>         END;
> $$ LANGUAGE plpgsql;

Control question, I didn't check it, but would it be enough to change from:
   UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
to:
   UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id AND text1 <> NEW.text1?

...  I may be wrong. :)

   Regards,
     Dawid

Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Dawid Kuroczko wrote:
> On 5/24/05, Sebastian Böck <sebastianboeck@freenet.de> wrote:
>
>>/* 3rd way of separating updates
>>   con: unnecessary updates on tables
>>   pro: view gets evaluated only 1 time
>>
>>   Not adressing the problem of unnecessary updates, but the view
>>   gets only evaluated one time.
>>
>>*/
>>
>>CREATE OR REPLACE FUNCTION upd (view_test) RETURNS VOID AS $$
>>        DECLARE
>>                NEW ALIAS FOR $1;
>>        BEGIN
>>                RAISE NOTICE 'UPDATE';
>>                UPDATE test SET test = NEW.test WHERE id = OLD.id;
>>                UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
>>                UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
>>                UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
>>                RETURN;
>>        END;
>>$$ LANGUAGE plpgsql;
>
>
> Control question, I didn't check it, but would it be enough to change from:
>    UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
> to:
>    UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id AND text1 <> NEW.text1?
>
> ...  I may be wrong. :)

Yes, thats more elegant then my other (4th) solution.
Was late yesterday evening ;)

Thanks

Sebastian

Re: Update on tables when the row doesn't change

From
Martijn van Oosterhout
Date:
Well, I havn't run the rule so I don't know exactly whether it is
relevent, but simply put, RULEs are like *macro substitution*. In
macros, if you specify an expression (like a view) as an argument, it
is placed as a whole each place the argument is used.

UPDATEs for different tables cannot be merged into a single query so
you get four queries and it's not clear how you could avoid any work.

I guess each subquery may be optimised individually, though I don't
know if it really helps. Perhaps you could show us the resulting query
plans and how you think they could be improved.

Have a nice day,

On Wed, May 25, 2005 at 10:40:38AM +0200, Sebastian Böck wrote:
> Thank you for the explanation. That's what I wanted to do first, but
> then I discovered that the view gets not only evaluated for every rule
> on it, but also gets evaluated as often as there are statements in one
> rule.
>
> Example:
>
> CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
>   DO INSTEAD (
>     UPDATE test SET test = NEW.test WHERE id = OLD.id;
>     UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
>     UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
>     UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
>   );
>
> Why gets the view evaluated 4 times?
>
> Thanks
>
> Sebastian

--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Attachment

Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Martijn van Oosterhout wrote:
> Well, I havn't run the rule so I don't know exactly whether it is
> relevent, but simply put, RULEs are like *macro substitution*. In
> macros, if you specify an expression (like a view) as an argument, it
> is placed as a whole each place the argument is used.

Yes I understood it the same way.
That makes absolutly sense in situations where you have different
rules on the same target (view or table).

> UPDATEs for different tables cannot be merged into a single query so
> you get four queries and it's not clear how you could avoid any work.
>
> I guess each subquery may be optimised individually, though I don't
> know if it really helps. Perhaps you could show us the resulting query
> plans and how you think they could be improved.

There are a lot of geometric operations involved (all done via
postgis) that make the view slow. I don't want to change the view
itself now, only want to get rid of all the unnecessary evaluations of
the view.

So I tried to collapse the rules into on rule as shown in the example
below:

> On Wed, May 25, 2005 at 10:40:38AM +0200, Sebastian Böck wrote:
>
>>CREATE OR REPLACE RULE upd AS ON UPDATE TO view_test
>>  DO INSTEAD (
>>    UPDATE test SET test = NEW.test WHERE id = OLD.id;
>>    UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
>>    UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
>>    UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
>>  );

I hoped that the view gets only evaluated once, because it is only one
rule, but thats not true :(

Thanks for all so far, I'll come back when tuning the obove mentioned
queries.

Sebastian

Re: Update on tables when the row doesn't change

From
Dawid Kuroczko
Date:
On 5/25/05, Sebastian Böck <sebastianboeck@freenet.de> wrote:
> >>CREATE OR REPLACE FUNCTION upd (view_test) RETURNS VOID AS $$
> >>        DECLARE
> >>                NEW ALIAS FOR $1;
> >>        BEGIN
> >>                RAISE NOTICE 'UPDATE';
> >>                UPDATE test SET test = NEW.test WHERE id = OLD.id;
> >>                UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
> >>                UPDATE join2 SET text2 = NEW.text2 WHERE id = OLD.id;
> >>                UPDATE join3 SET text3 = NEW.text3 WHERE id = OLD.id;
> >>                RETURN;
> >>        END;
> >>$$ LANGUAGE plpgsql;
> >
> >
> > Control question, I didn't check it, but would it be enough to change from:
> >    UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
> > to:
> >    UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id AND text1 <> NEW.text1?
> >
> > ...  I may be wrong. :)
>
> Yes, thats more elegant then my other (4th) solution.
> Was late yesterday evening ;)

Be wary of the NULL values though. :)  Either don't use them, add
something like 'AND (text1 <> NEW.text1 OR text1 IS NULL OR NEW.text1
IS NULL)' or something more complicated. :)

   Regards,
         Dawid

Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Dawid Kuroczko wrote:

>>>Control question, I didn't check it, but would it be enough to change from:
>>>   UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id;
>>>to:
>>>   UPDATE join1 SET text1 = NEW.text1 WHERE id = OLD.id AND text1 <> NEW.text1?
>>>
>>>...  I may be wrong. :)
>>
>>Yes, thats more elegant then my other (4th) solution.
>>Was late yesterday evening ;)
>
>
> Be wary of the NULL values though. :)  Either don't use them, add
> something like 'AND (text1 <> NEW.text1 OR text1 IS NULL OR NEW.text1
> IS NULL)' or something more complicated. :)

Thanks for the notice, but I have a special operator for this:

CREATE OR REPLACE FUNCTION different (ANYELEMENT, ANYELEMENT) RETURNS
BOOLEAN AS $$
   BEGIN
    IF ($1 <> $2) OR ($1 IS NULL <> $2 IS NULL) THEN
       RETURN TRUE;
    ELSE
      RETURN FALSE;
   END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

CREATE OPERATOR <<>> (
    LEFTARG = ANYELEMENT,
    RIGHTARG = ANYELEMENT,
    PROCEDURE = different,
    COMMUTATOR = <<>>,
    NEGATOR = ====
);

Sebastian

Re: Update on tables when the row doesn't change

From
Ragnar Hafstað
Date:
On Wed, 2005-05-25 at 13:09 +0200, Sebastian Böck wrote:
> Dawid Kuroczko wrote:
>
> >
> > Be wary of the NULL values though. :)  Either don't use them, add
> > something like 'AND (text1 <> NEW.text1 OR text1 IS NULL OR NEW.text1
> > IS NULL)' or something more complicated. :)
>
> Thanks for the notice, but I have a special operator for this:
>
> CREATE OR REPLACE FUNCTION different (ANYELEMENT, ANYELEMENT) RETURNS

and then there is the 'IS DISTINCT FROM' construct
http://www.postgresql.org/docs/8.0/static/functions-comparison.html#AEN6094

gnari



Re: Update on tables when the row doesn't change

From
Sebastian Böck
Date:
Ragnar Hafstað wrote:
> On Wed, 2005-05-25 at 13:09 +0200, Sebastian Böck wrote:
>
>>Dawid Kuroczko wrote:
>>
>>
>>>Be wary of the NULL values though. :)  Either don't use them, add
>>>something like 'AND (text1 <> NEW.text1 OR text1 IS NULL OR NEW.text1
>>>IS NULL)' or something more complicated. :)
>>
>>Thanks for the notice, but I have a special operator for this:
>>
>>CREATE OR REPLACE FUNCTION different (ANYELEMENT, ANYELEMENT) RETURNS
>
>
> and then there is the 'IS DISTINCT FROM' construct
> http://www.postgresql.org/docs/8.0/static/functions-comparison.html#AEN6094
>

Much easier :)

Thanks

Sebastian

Re: Update on tables when the row doesn't change

From
"Tim Vadnais"
Date:
Hi All,

Can someone please address this aspect of Sebastian's email?  I, too, am
interested in the response.

>> Why does Postgres perform an update on the table even
>> if no data changes?
>> Can I circumvent this behaviour of Postgres?

Tim

-----Original Message-----
From: pgsql-general-owner@postgresql.org
[mailto:pgsql-general-owner@postgresql.org] On Behalf Of Sebastian Böck
Sent: Tuesday, May 24, 2005 8:06 AM
To: pgsql-general@postgresql.org
Subject: [GENERAL] Update on tables when the row doesn't change

Hi all,

Maybe it's a very silly question, but why does Postgres perform an update on
the table even if no data changes?

I recognized this recently doing a rewrite of my rules because they took to
long. I had many conditional rules I collapsed to one unconditional rule, so
that the views get constructed only once. If I split these updates to the
underlying tables, I get a lot of updates which don't perform any "real"
updates.

Can I circumvent this behaviour of Postgres only by defining lot of rules /
triggers on these underlying table are there some trickier ways?

Any help appreciated,

Sebastian

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
      subscribe-nomail command to majordomo@postgresql.org so that your
      message can get through to the mailing list cleanly



Re: Update on tables when the row doesn't change

From
Scott Marlowe
Date:
On Wed, 2005-05-25 at 10:41, Tim Vadnais wrote:

> >> Why does Postgres perform an update on the table even
> >> if no data changes?
> >> Can I circumvent this behaviour of Postgres?
> >>
> Hi All,
>
> Can someone please address this aspect of Sebastian's email?  I, too, am
> interested in the response.
>

Actually, I believe it was addressed by Tom, when he said that it would
be more costly to check every single update to see if there WAS a change
before applying it than to just apply the changes every time.

I concur.  Can you imagine slowing down ALL updates by 5% or something
like that just to prevent the rare case where an update didn't actually
change a value?

Re: Update on tables when the row doesn't change

From
Martijn van Oosterhout
Date:
On Wed, May 25, 2005 at 08:41:23AM -0700, Tim Vadnais wrote:
> Hi All,
>
> Can someone please address this aspect of Sebastian's email?  I, too, am
> interested in the response.
>
> >> Why does Postgres perform an update on the table even
> >> if no data changes?
> >> Can I circumvent this behaviour of Postgres?

Tom did, AFAIK. Basically, it's a non-zero cost to check for something
that's useless in 99.99% of cases. Secondly, if you have a update
trigger on the table, it applies to all updates, even if they don't
change the actual data. If you didn't want to update the row, don't
issue it in the first place.

If you want to block the update, create your own trigger to detect it
and drop it. Most people don't need it.

That's completely seperate to his issue with reevaluating the view,
where I've seen no response to the question about what he thinks
PostgreSQL should be doing. You know, the query plan he get vs what he
actually wants.

Hope this helps,
--
Martijn van Oosterhout   <kleptog@svana.org>   http://svana.org/kleptog/
> Patent. n. Genius is 5% inspiration and 95% perspiration. A patent is a
> tool for doing 5% of the work and then sitting around waiting for someone
> else to do the other 95% so you can sue them.

Attachment