Thread: Delete performance
Hi All My database uses joined table inheritance and my server version is 9.0 Version string PostgreSQL 9.0rc1 on x86_64-pc-linux-gnu, compiled by GCC x86_64-pc-linux-gnu-gcc (Gentoo 4.4.4-r1 p1.1,pie-0.4.5) 4.4.4, 64-bit I have about 120,000 records in the table that everything else inherits from, if i truncate-cascaded this table it happensalmost instantly. If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it takes close to 10 minutes. My foreign keys to the base table are all set with "ON DELETE CASCADE". I've looked though all the feilds that relate tothe "ID" in the base table and created btree indexes for them. Can anyone outline what I need to verify/do to ensure i'm getting the best performance for my deletes? Regards, Jarrod Chesney
9.0rc1 ? You know that the stable 9.0 has been out for quite a while now. Its not going to affect the delete speed in any way, but I would generally advice you to upgrade it to the lates 9.0.x As for the delete it self, check if you have indices on the tables that refer the main table on the referred column. Often times that's the issue. Other thing is , number of triggers on the other tables. -- GJ
> If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it > takes close to 10 minutes. Do you run those in a single transaction or do you use one transaction per DELETE ? In the latter case, postgres will ensure each transaction is commited to disk, at each commit. Since this involves waiting for the physical I/O to happen, it is slow. If you do it 30.000 times, it will be 30.000 times slow. Note that you should really do : DELETE FROM table WHERE id IN (huge list of ids). or DELETE FROM table JOIN VALUES (list of ids) ON (...) Also, check your foreign keys using cascading deletes have indexes in the referencing tables. Without an index, finding the rows to cascade-delete will be slow.
On 1/06/2011 7:11 AM, Pierre C wrote: >> If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it >> takes close to 10 minutes. > > Do you run those in a single transaction or do you use one transaction > per DELETE ? > > In the latter case, postgres will ensure each transaction is commited to > disk, at each commit. Since this involves waiting for the physical I/O > to happen, it is slow. If you do it 30.000 times, it will be 30.000 > times slow. Not only that, but if you're doing it via some application the app has to wait for Pg to respond before it can send the next query. This adds even more delay, as do all the processor switches between Pg and your application. If you really must issue individual DELETE commands one-by-one, I *think* you can use synchronous_commit=off or SET LOCAL synchronous_commit TO OFF; See: http://www.postgresql.org/docs/current/static/runtime-config-wal.html -- Craig Ringer Tech-related writing at http://soapyfrogs.blogspot.com/
I'm executing 30,000 single delete statements in one transaction. At this point i'm looking into combining the multiple deletes into one statement and breaking my big transaction into smallerones of about 100 deletes or so. On 01/06/2011, at 11:40 AM, Craig Ringer wrote: > On 1/06/2011 7:11 AM, Pierre C wrote: >>> If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it >>> takes close to 10 minutes. >> >> Do you run those in a single transaction or do you use one transaction >> per DELETE ? >> >> In the latter case, postgres will ensure each transaction is commited to >> disk, at each commit. Since this involves waiting for the physical I/O >> to happen, it is slow. If you do it 30.000 times, it will be 30.000 >> times slow. > > Not only that, but if you're doing it via some application the app has to wait for Pg to respond before it can send thenext query. This adds even more delay, as do all the processor switches between Pg and your application. > > If you really must issue individual DELETE commands one-by-one, I *think* you can use synchronous_commit=off or > > SET LOCAL synchronous_commit TO OFF; > > See: > > http://www.postgresql.org/docs/current/static/runtime-config-wal.html > > > -- > Craig Ringer > > Tech-related writing at http://soapyfrogs.blogspot.com/
On 05/30/2011 08:08 PM, Jarrod Chesney wrote: > My database uses joined table inheritance and my server version is 9.0 > I have about 120,000 records in the table that everything else inherits from, if i truncate-cascaded this table it happensalmost instantly. If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it takes close to 10 minutes. > > My foreign keys to the base table are all set with "ON DELETE CASCADE". You may also want to make them DEFERRABLE and then use "SET CONSTRAINTS ALL DEFERRABLE" so that the constraint checking all happens at one time. This will cause more memory to be used, but all the constraint related work will happen in a batch. You mentioned inheritance. That can cause some unexpected problems sometimes. You might want to do: EXPLAIN DELETE FROM ... To see how this is executing. EXPLAIN works fine on DELETE statements, too, and it may highlight something strange about how the deletion is happening. If you can, use EXPLAIN ANALYZE, but note that this will actually execute the statement--the deletion will happen, it's not just a test. There may be a problem with the query plan for the deletion that's actually causing the issue here, such as missing the right indexes. If you have trouble reading it, http://explain.depesz.com/ is a good web resources to help break down where the time is going. -- Greg Smith 2ndQuadrant US greg@2ndQuadrant.com Baltimore, MD PostgreSQL Training, Services, and 24x7 Support www.2ndQuadrant.us "PostgreSQL 9.0 High Performance": http://www.2ndQuadrant.com/books
On 01/06/2011, at 11:45 AM, Jarrod Chesney wrote: > I'm executing 30,000 single delete statements in one transaction. > > At this point i'm looking into combining the multiple deletes into one statement and breaking my big transaction into smallerones of about 100 deletes or so. > > On 01/06/2011, at 11:40 AM, Craig Ringer wrote: > >> On 1/06/2011 7:11 AM, Pierre C wrote: >>>> If i run 30,000 prepared "DELETE FROM xxx WHERE "ID" = ?" commands it >>>> takes close to 10 minutes. >>> >>> Do you run those in a single transaction or do you use one transaction >>> per DELETE ? >>> >>> In the latter case, postgres will ensure each transaction is commited to >>> disk, at each commit. Since this involves waiting for the physical I/O >>> to happen, it is slow. If you do it 30.000 times, it will be 30.000 >>> times slow. >> >> Not only that, but if you're doing it via some application the app has to wait for Pg to respond before it can send thenext query. This adds even more delay, as do all the processor switches between Pg and your application. >> >> If you really must issue individual DELETE commands one-by-one, I *think* you can use synchronous_commit=off or >> >> SET LOCAL synchronous_commit TO OFF; >> >> See: >> >> http://www.postgresql.org/docs/current/static/runtime-config-wal.html >> >> >> -- >> Craig Ringer >> >> Tech-related writing at http://soapyfrogs.blogspot.com/ > Apologies for top posting, Sorry.