Thread: Poor performance of delete by primary key

Poor performance of delete by primary key

From
"Brian Choate"
Date:

Hello,

We are seeing a very strange behavior from postgres. For one of our very common tasks we have to delete records from a table of around 500,000 rows. The delete is by id which is the primary key. It seems to be consistently taking around 10 minutes to preform. This is totally out of line with the rest of the performance of the database.

This table does have children through foreign keys, but I am pretty sure that all foreign key constraints in the schema have indexes on their children.

Sometimes if we do a vacuum right before running the process the delete will go much faster. But then the next time we run the task, even just a few minutes later, the delete takes a long time to run.

We deploy the same application also on Oracle. The schemas are pretty much identical. On similar hardware with actually about 4 to 5 times the data, Oracle does not seem to have the same problem. Not that that really means anything since the internals of Oracle and PostgreSQL are so different, but an interesting fact anyway.

Any ideas on what might be going on?

Thanks,
B.

Re: Poor performance of delete by primary key

From
Tom Lane
Date:
"Brian Choate" <brianc@nimblefish.com> writes:
> We are seeing a very strange behavior from postgres. For one of our very =
> common tasks we have to delete records from a table of around 500,000 =
> rows. The delete is by id which is the primary key. It seems to be =
> consistently taking around 10 minutes to preform. This is totally out of =
> line with the rest of the performance of the database.

I'll bet this table has foreign-key references from elsewhere, and the
referencing columns are either not indexed, or not of the same datatype
as the master column.

Unfortunately there's no very simple way to determine which FK is the
problem.  (In 8.1 it'll be possible to do that with EXPLAIN ANALYZE,
but in existing releases EXPLAIN doesn't break out the time spent in
each trigger ...)  You have to just eyeball the schema :-(.

            regards, tom lane

Re: Poor performance of delete by primary key

From
Matthew Sackman
Date:
On Tue, Sep 06, 2005 at 11:32:00AM -0400, Tom Lane wrote:
> "Brian Choate" <brianc@nimblefish.com> writes:
> > We are seeing a very strange behavior from postgres. For one of our very =
> > common tasks we have to delete records from a table of around 500,000 =
> > rows. The delete is by id which is the primary key. It seems to be =
> > consistently taking around 10 minutes to preform. This is totally out of =
> > line with the rest of the performance of the database.
>
> I'll bet this table has foreign-key references from elsewhere, and the
> referencing columns are either not indexed, or not of the same datatype
> as the master column.

Wouldn't setting the FK as deferrable and initially deferred help here
too as then the FK wouldn't be checked until the transaction ended?

Matthew

Re: Poor performance of delete by primary key

From
Richard Huxton
Date:
Brian Choate wrote:
> Hello,
>
> We are seeing a very strange behavior from postgres. For one of our
> very common tasks we have to delete records from a table of around
> 500,000 rows. The delete is by id which is the primary key. It seems
> to be consistently taking around 10 minutes to preform. This is
> totally out of line with the rest of the performance of the database.

> Any ideas on what might be going on?

Well, it sounds like *something* isn't using an index. You say that all
your FK's are indexed, but that's something worth checking. Also keep an
eye out for type conflicts.

If the system is otherwise idle, it might be worthwhile to compare
before and after values of pg_stat* (user-tables and user-indexes).

--
   Richard Huxton
   Archonet Ltd

Re: Poor performance of delete by primary key

From
Mark Lewis
Date:
I had a similar problem, so I downloaded 8.1 from CVS, ran it on a
relatively gnarly dev workstation, imported a dump of my 8.0 database,
and ran my troublesome queries with the new EXPLAIN ANALYZE.

This process took about an hour and worked great, provided that you've
actually named your foreign key constraints.  Otherwise, you'll find out
that there's a trigger for a constraint called $3 that's taking up all
of your time, but you won't know what table that constraint is on.

-- Mark



On Tue, 2005-09-06 at 11:32 -0400, Tom Lane wrote:
> "Brian Choate" <brianc@nimblefish.com> writes:
> > We are seeing a very strange behavior from postgres. For one of our very =
> > common tasks we have to delete records from a table of around 500,000 =
> > rows. The delete is by id which is the primary key. It seems to be =
> > consistently taking around 10 minutes to preform. This is totally out of =
> > line with the rest of the performance of the database.
>
> I'll bet this table has foreign-key references from elsewhere, and the
> referencing columns are either not indexed, or not of the same datatype
> as the master column.
>
> Unfortunately there's no very simple way to determine which FK is the
> problem.  (In 8.1 it'll be possible to do that with EXPLAIN ANALYZE,
> but in existing releases EXPLAIN doesn't break out the time spent in
> each trigger ...)  You have to just eyeball the schema :-(.
>
>             regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 3: Have you checked our extensive FAQ?
>
>                http://www.postgresql.org/docs/faq


Re: Poor performance of delete by primary key

From
Tom Lane
Date:
Mark Lewis <mark.lewis@mir3.com> writes:
> I had a similar problem, so I downloaded 8.1 from CVS, ran it on a
> relatively gnarly dev workstation, imported a dump of my 8.0 database,
> and ran my troublesome queries with the new EXPLAIN ANALYZE.

> This process took about an hour and worked great, provided that you've
> actually named your foreign key constraints.  Otherwise, you'll find out
> that there's a trigger for a constraint called $3 that's taking up all
> of your time, but you won't know what table that constraint is on.

But at least you've got something you can work with.  Once you know the
name of the problem trigger you can look in pg_trigger to see which
other table it's connected to.  Try something like

    select tgname, tgconstrrelid::regclass, tgargs from pg_trigger
    where tgrelid = 'mytable'::regclass;

            regards, tom lane

Re: Poor performance of delete by primary key

From
Christopher Kings-Lynne
Date:
> Unfortunately there's no very simple way to determine which FK is the
> problem.  (In 8.1 it'll be possible to do that with EXPLAIN ANALYZE,
> but in existing releases EXPLAIN doesn't break out the time spent in
> each trigger ...)  You have to just eyeball the schema :-(.

phpPgAdmin has a handy info feature where you can see all tables that
refer to the current one.  You can always go and steal that query to
find them...

Chris

Re: Poor performance of delete by primary key

From
"Jim C. Nasby"
Date:
On Wed, Sep 07, 2005 at 11:07:04AM +0800, Christopher Kings-Lynne wrote:
> >Unfortunately there's no very simple way to determine which FK is the
> >problem.  (In 8.1 it'll be possible to do that with EXPLAIN ANALYZE,
> >but in existing releases EXPLAIN doesn't break out the time spent in
> >each trigger ...)  You have to just eyeball the schema :-(.
>
> phpPgAdmin has a handy info feature where you can see all tables that
> refer to the current one.  You can always go and steal that query to
> find them...

You can also use pg_user_foreighn_key* from
http://pgfoundry.org/projects/newsysviews/.
--
Jim C. Nasby, Sr. Engineering Consultant      jnasby@pervasive.com
Pervasive Software      http://pervasive.com    work: 512-231-6117
vcard: http://jim.nasby.net/pervasive.vcf       cell: 512-569-9461