Received: from localhost (maia-3.hub.org [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id F1DA39FB8E2 for ; Mon, 11 Jun 2007 12:41:36 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 42197-04 for ; Mon, 11 Jun 2007 12:41:33 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from mail.emolecules.com (66-226-76-106.dedicated.abac.net [66.226.76.106]) by postgresql.org (Postfix) with ESMTP id 52E419FB846 for ; Mon, 11 Jun 2007 12:41:33 -0300 (ADT) Received: (qmail 25133 invoked by uid 2020); 11 Jun 2007 08:41:32 -0700 Received: from wsip-68-224-174-233.sd.sd.cox.net (HELO ?192.168.0.3?) (68.224.174.233) by 192.168.0.4 with SMTP; 11 Jun 2007 08:41:31 -0700 Message-ID: <466D6DDE.7030006@emolecules.com> Date: Mon, 11 Jun 2007 08:44:30 -0700 From: Craig James User-Agent: Thunderbird 1.5.0.12 (X11/20070509) MIME-Version: 1.0 To: "Tyrrill, Ed" CC: pgsql-performance@postgresql.org Subject: Re: Best way to delete unreferenced rows? References: <46688BC5.3020006@emolecules.com> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.08 tagged_above=0 required=5 tests=AWL=-0.056, BAYES_50=0.001, FORGED_RCVD_HELO=0.135 X-Spam-Level: X-Archive-Number: 200706/190 X-Sequence-Number: 25223 Tyrrill, Ed wrote: > QUERY PLAN > > ------------------------------------------------------------------------ > ------------------------------------------------------------------------ > ------------------- > Merge Left Join (cost=38725295.93..42505394.70 rows=13799645 width=8) > (actual time=6503583.342..8220629.311 rows=93524 loops=1) > Merge Cond: ("outer".record_id = "inner".record_id) > Filter: ("inner".record_id IS NULL) > -> Index Scan using backupobjects_pkey on backupobjects > (cost=0.00..521525.10 rows=13799645 width=8) (actual > time=15.955..357813.621 rows=13799645 loops=1) > -> Sort (cost=38725295.93..39262641.69 rows=214938304 width=8) > (actual time=6503265.293..7713657.750 rows=214938308 loops=1) > Sort Key: backup_location.record_id > -> Seq Scan on backup_location (cost=0.00..3311212.04 > rows=214938304 width=8) (actual time=11.175..1881179.825 rows=214938308 > loops=1) > Total runtime: 8229178.269 ms > (8 rows) > > I ran vacuum analyze after the last time any inserts, deletes, or > updates were done, and before I ran the query above. I've attached my > postgresql.conf. The machine has 4 GB of RAM. I thought maybe someone with more expertise than me might answer this, but since they haven't I'll just make a comment. It looks to me like the sort of 214 million rows is what's killing you. I suppose you could try to increase the sort memory, but that's a lot of memory. It seems to me an index merge of a relation this large would be faster, but that's a topic for the experts. On a theoretical level, the problem is that it's sorting the largest table. Perhaps you could re-cast the query so that it only has to sort the smaller table, something like select a.id from a where a.id not in (select distinct b.id from b) where "b" is the smaller table. There's still no guarantee that it won't do a sort on "a", though. In fact one of the clever things about Postgres is that it can convert a query like the one above into a regular join, unless you do something like "select ... offset 0" which blocks the optimizer from doing the rearrangement. But I think the first approach is to try to tune for a better plan using your original query. Craig