Thread: Delete performance

Delete performance

From
Jarrod Chesney
Date:
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

Re: Delete performance

From
Grzegorz Jaśkiewicz
Date:
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

Re: Delete performance

From
"Pierre C"
Date:
> 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.

Re: Delete performance

From
Craig Ringer
Date:
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/

Re: Delete performance

From
Jarrod Chesney
Date:
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/


Re: Delete performance

From
Greg Smith
Date:
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


Re: Delete performance

From
Jarrod Chesney
Date:
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.