Received: from maia.hub.org (maia-3.hub.org [200.46.204.243]) by mail.postgresql.org (Postfix) with ESMTP id 1A1A51337B54 for ; Sat, 12 Feb 2011 04:09:45 -0400 (AST) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.243]) (amavisd-maia, port 10024) with ESMTP id 05381-07 for ; Sat, 12 Feb 2011 08:09:37 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from smtpcorp.com (smtpcorp.com [174.143.60.32]) by mail.postgresql.org (Postfix) with ESMTP id 80B8D1337B51 for ; Sat, 12 Feb 2011 04:09:36 -0400 (AST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpcorp.com; s=main; h=Content-Transfer-Encoding:Content-Type:Mime-Version:References:Message-ID:Date:Subject:From:To; bh=PbqnEVQbGcLicXhXpsuvpjQUZdQaw9m+SRdj+fHDU2Q=; b=QhKDc2MgKkNlbP29jK0AK3Pia+wqFuFoC4UdjK2n1EP1L9TTXWZPUk7tCdWY7/CuN8bi+BjDlipLuo53DOLMec4n8vwOVyWfF/nXK9hwkX2zaqBJNzR03HOqSAgU3xYa; Received: from ip-118-90-143-71.xdsl.xnet.co.nz ([118.90.143.71] helo=gonzo) by smtpcorp.com with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.70) id 1PoAXy-0002q6-1Z; mid 144 for pgsql-sql@postgresql.org; Sat, 12 Feb 2011 08:09:38 +0000 Received: from news by gonzo with local (Exim 4.72) (envelope-from ) id 1PoAXh-0007bV-Ul for pgsql-sql@postgresql.org; Sat, 12 Feb 2011 21:09:21 +1300 To: pgsql-sql@postgresql.org Path: not-for-mail From: Jasen Betts Newsgroups: gmane.comp.db.postgresql.sql Subject: Re: DELETE FROM takes forever Date: 12 Feb 2011 08:09:21 GMT Organization: Dis (not Dat) Organisation Lines: 60 Message-ID: References: NNTP-Posting-Host: localhost Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Trace: reversiblemaps.ath.cx 1297498161 29231 127.0.0.1 (12 Feb 2011 08:09:21 GMT) X-Face: ?)Aw4rXwN5u0~$nqKj`xPz>xHCwgi^q+^?Ri*+R(&uv2=E1Q0Zk(>h!~o2ID@6{uf8s; a +M[5[U[QT7xFN%^gR"=tuJw%TXXR'Fp~W; (T"1(739R%m0Yyyv*gkGoPA.$b,D.w:z+<'"=-lVT?6 {T?=R^:W5g|E2#EhjKCa+nt":4b}dU7GYB*HBxn&Td$@f%.kl^:7X8rQWd[NTc"P"u6nkisze/Q; 8 "9Z{peQF,w)7UjV$c|RO/mQW/NMgWfr5*$-Z%u46"/00mx-,\R'fLPe.)^ User-Agent: slrn/pre1.0.0-18 (Linux) X-Smtpcorp-Track: 22854056.1.43498180 X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.9 tagged_above=-5 required=5 tests=BAYES_00=-1.9 X-Spam-Level: X-Archive-Number: 201102/59 X-Sequence-Number: 35135 On 2011-02-10, Josh wrote: > Hi > > I'm trying to do a DELETE FROM on my large table (about 800 million > rows) based on the contents of another, moderately large table (about > 110 million rows). The command I'm using is: > > DELETE FROM records WHERE id NOT IN (SELECT id FROM unique_records); > > This process ran for about two weeks before I decided to stop it -- it > was dragging down the DB server. I can understand long-running > processes, but two weeks seems a bit much even for a big table. I find that scripting deletes of smaller numbers of records can help here, long-running queries do bad things to the efficiency of postgres. on strategy that could work for your task would be to create a temp table first: create temp table planned_deletions as select id from records except SELECT id FROM unique_records; create index badids on planned_deletions(id); the repeatedly delete from records where id in ( select id from planned_deletions limit 10000 order by id); delete from planned_deletions where id in ( select id from planned_deletions limit 10000 order by id); until there are none left. possibly pausing a few seconds between each slug if there is a heavy load on the server (that you were able to run the query for 2 weeks suggests that there may not be). > Is this the best way to approach the problem? Is there a better way? > > Some background: The server is version 8.3, running nothing but Pg. > The 'records' table has 'id' as its primary key, and one other index > on another column. The table is referenced by just about every other > table in my DB (about 15 other tables) via foreign key constraints, > which I don't want to break (which is why I'm not just recreating the > table rather than deleting rows). Most of the dependent tables have ON > DELETE CASCADE. The 'unique_records' table is a temp table I got via > something like: SELECT DISTINCT (other_column) id INTO unique_records > FROM records if you can accept the down-time I would drop the constraints (if you don't have them on file do a pg_dump --schema-only , and grep it for the ADD CONSTRIANT commands, use sed or similar to create matching DROP CONSTRAINT commands, run them) then rebuild the table then reintroduce the constraints, keep a copy of the grep output above -- ⚂⚃ 100% natural