Thread: Poor performance of delete by primary key
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.
"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
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
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
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
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
> 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
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