Thread: Perfornamce Q

Perfornamce Q

From
Jean-Christian Imbeault
Date:
Doing a simple update on all the rows of a table takes longer than I
would expect it and I am wondering if there is something I can do to
improve the performance:

The table contains 15193 rows:

Here is the time for updating all rows:

TAL2=# vacuum full analyze;
VACUUM
TAL2=# update products set point_margin=1;
UPDATE 15193
Time: 14585.63 ms

Here is the explain in case it is of any help:

TAL2=# explain analyze update products set point_margin=1;
\d products
                                                    QUERY PLAN

-----------------------------------------------------------------------------------------------------------------
  Seq Scan on products  (cost=0.00..1031.93 rows=15193 width=416)
(actual time=50.57..2432.20 rows=15193 loops=1)
  Total runtime: 12567.58 msec
(2 rows)

I know 14 secs doesn't sound like a lot but I would have thought that
since the query is so simple it would quite fast. I did the same thing
on a test table with only one field and it took only 0.3 secs ...

TAL2=# create table test (t integer default 0);
CREATE TABLE
TAL2=# insert into test(t) select id from products;
INSERT 0 15193
Time: 1655.33 ms
TAL2=# update test set t=0;
UPDATE 15193
Time: 331.87 ms


My products table has 16 rows and the following constraints, but none of
the constraints are on the row I am updating so I can't see why the
update takes so long ...

TAL2=# \d products
                                            Table "public.products"
      Column      |              Type              |
     Modifiers
-----------------+--------------------------------+----------------------------------------------------------
  id              | integer                        | not null default
nextval('public.products_id_seq'::text)
  navi_id         | text                           | not null
  prod_type_id    | integer                        |
  name            | text                           |
  name_kana       | text                           |
  buy_price       | integer                        | default 0
  sell_price      | integer                        | not null
  point_margin    | smallint                       | default 0
  maker_id        | integer                        |
  maker_prod_code | text                           |
  maker_comment   | text                           |
  haiban          | boolean                        |
  jan_code        | text                           |
  retail_price    | integer                        |
  distributor_id  | integer                        | not null
  upload_time     | timestamp(0) without time zone | not null default now()
Indexes: products_pkey primary key btree (id),
          products_navi_id_key unique btree (navi_id)
Foreign Key constraints: $3 FOREIGN KEY (distributor_id) REFERENCES
distributors(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
                          $2 FOREIGN KEY (maker_id) REFERENCES
makers(id) ON UPDATE NO ACTION ON DELETE NO ACTION,
                          $1 FOREIGN KEY (prod_type_id) REFERENCES
product_types(id) ON UPDATE NO ACTION ON DELETE NO ACTION


Can anyone offering suggestions as to why the UPDATE takes so long and
what I might do to make it go faster?

Thanks!

Jc


Re: Perfornamce Q

From
Tom Lane
Date:
Jean-Christian Imbeault <jc@mega-bucks.co.jp> writes:
> Can anyone offering suggestions as to why the UPDATE takes so long and
> what I might do to make it go faster?

I think it's the foreign keys that are hurting you.  Are the referenced
columns indexed?  Are they of the same datatypes as the referencing
columns?  Have you ANALYZEd those tables lately?

            regards, tom lane

Re: Perfornamce Q

From
Jean-Christian Imbeault
Date:
Tom Lane wrote:
>
> I think it's the foreign keys that are hurting you.  Are the referenced
> columns indexed?

They should be, they are all primary keys in the referenced tables.

But why would they be hurting me? The update is on a column that has no
constraints on it. If the foreign key constraints are hurting me I don't
understand the reason ... could you explain why?

> Are they of the same datatypes as the referencing
> columns?

They must be no? Otherwise how could they be foreign key constraints?
(And I just checked and yes they are of the same type).

> Have you ANALYZEd those tables lately?

In the output I gave the first thing I did was a "vacuum full analyze".
I have actually found that the time require usually goes *up* strangely
enough after doing a vacuum full analyze though ...

Jc


Re: Perfornamce Q

From
Tom Lane
Date:
Jean-Christian Imbeault <jc@mega-bucks.co.jp> writes:
> But why would they be hurting me? The update is on a column that has no
> constraints on it.

Doesn't matter: any update will fire the foreign-key check trigger.

Whether this is necessary or not I dunno, but someone's thought of
it before: in the code I see
    /*
     * Note: We cannot avoid the check on UPDATE, even if old and new key
     * are the same. Otherwise, someone could DELETE the PK that consists
     * of the DEFAULT values, and if there are any references, a ON DELETE
     * SET DEFAULT action would update the references to exactly these
     * values but we wouldn't see that weired case (this is the only place
     * to see it).
     */


            regards, tom lane

Re: Perfornamce Q

From
Jean-Christian Imbeault
Date:
Tom Lane wrote:
>
> Doesn't matter: any update will fire the foreign-key check trigger.
>
> Whether this is necessary or not I dunno, but someone's thought of
> it before: in the code I see
>     /*
>      * Note: We cannot avoid the check on UPDATE, even if old and new key
>      * are the same. Otherwise, someone could DELETE the PK that consists
>      * of the DEFAULT values, and if there are any references, a ON DELETE
>      * SET DEFAULT action would update the references to exactly these
>      * values but we wouldn't see that weired case (this is the only place
>      * to see it).
>      */

I don't quite understand the comment but I guess it mean that an "ON
DELETE SET DEFAULT" might be triggered by an UPDATE, and that "ON DELETE
SET DEFAULT" might affect the PK, AND because of this possible scenario
the FK check is needed.

Is there any way for me to turn the behaviour off during my updates?

Could this be added to the to-do list (if feasible)?

- skip FK (any?) constraint checks on UPDATE if the affected update
column(s) have no constraints/check on them.

Thanks,

Jc


Re: Perfornamce Q

From
Stephan Szabo
Date:
On Thu, 23 Jan 2003, Tom Lane wrote:

> Jean-Christian Imbeault <jc@mega-bucks.co.jp> writes:
> > But why would they be hurting me? The update is on a column that has no
> > constraints on it.
>
> Doesn't matter: any update will fire the foreign-key check trigger.
>
> Whether this is necessary or not I dunno, but someone's thought of
> it before: in the code I see
>     /*
>      * Note: We cannot avoid the check on UPDATE, even if old and new key
>      * are the same. Otherwise, someone could DELETE the PK that consists
>      * of the DEFAULT values, and if there are any references, a ON DELETE
>      * SET DEFAULT action would update the references to exactly these
>      * values but we wouldn't see that weired case (this is the only place
>      * to see it).
>      */

Since this is only necessary when the delete action is SET DEFAULT, I've
been planning to change it to always do the check on ON DELETE SET DEFAULT
or in other cases see if the key has changed and do the check only then.



Re: Perfornamce Q

From
Stephan Szabo
Date:
On Thu, 23 Jan 2003, Jean-Christian Imbeault wrote:

> Tom Lane wrote:
> >
> > Doesn't matter: any update will fire the foreign-key check trigger.
> >
> > Whether this is necessary or not I dunno, but someone's thought of
> > it before: in the code I see
> >     /*
> >      * Note: We cannot avoid the check on UPDATE, even if old and new key
> >      * are the same. Otherwise, someone could DELETE the PK that consists
> >      * of the DEFAULT values, and if there are any references, a ON DELETE
> >      * SET DEFAULT action would update the references to exactly these
> >      * values but we wouldn't see that weired case (this is the only place
> >      * to see it).
> >      */
>
> I don't quite understand the comment but I guess it mean that an "ON
> DELETE SET DEFAULT" might be triggered by an UPDATE, and that "ON DELETE
> SET DEFAULT" might affect the PK, AND because of this possible scenario
> the FK check is needed.

The case is if you have ON DELETE SET DEFAULT and you delete the PK row
that is the matching row for the defaults on the FK table (and there are
rows already having that value) it would attempt to update the row to the
default values which would then fire the update/insert trigger which
would see that the row values haven't changed and not check the rows, but
that's wrong because the constraint is violated.