Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id B724FB5DE87 for ; Tue, 25 Oct 2011 15:45:47 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 05921-01-10 for ; Tue, 25 Oct 2011 18:45:41 +0000 (UTC) Received: from mx1.hub.org (mx1.hub.org [200.46.208.106]) by mail.postgresql.org (Postfix) with ESMTP id 6A570B5DCDB for ; Tue, 25 Oct 2011 15:37:48 -0300 (ADT) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0-rc2 Received: from mail-gy0-f174.google.com (mail-gy0-f174.google.com [209.85.160.174]) by mx1.hub.org (Postfix) with ESMTP id 7635A27FBA49 for ; Tue, 25 Oct 2011 15:37:43 -0300 (ADT) Received: by gyb13 with SMTP id 13so775670gyb.19 for ; Tue, 25 Oct 2011 11:37:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:content-type:content-transfer-encoding:subject:date:message-id :to:mime-version:x-mailer; bh=6eOI8hiTbXFEaSp+Yfhe2JVF/x0YOvGuGSjJii01v+8=; b=lXWOZIYbKVXkWrdrCVaD5zbv3pnweTaCXxncClxdnFowR8Bb5BFCaf4Et+Tmyc/LBD l5JiGmJ3ohyOAGVmRV0R8AnGbkEZKewbCqQz0QZ9XGM9gpZnI0r/OfasfWH/rDtip0Hf p75U+rWAJEUKqLSp19yB7w7+Eln/m3lDugu6c= Received: by 10.101.166.33 with SMTP id t33mr4376033ano.158.1319567825074; Tue, 25 Oct 2011 11:37:05 -0700 (PDT) Received: from [192.168.1.101] (cpe-72-230-216-254.stny.res.rr.com. [72.230.216.254]) by mx.google.com with ESMTPS id f32sm18030002ani.20.2011.10.25.11.37.03 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 25 Oct 2011 11:37:04 -0700 (PDT) From: Ty Busby Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: optimize self-join query Date: Tue, 25 Oct 2011 14:37:02 -0400 Message-Id: To: pgsql-sql@postgresql.org Mime-Version: 1.0 (Apple Message framework v1251.1) X-Mailer: Apple Mail (2.1251.1) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.889 tagged_above=-5 required=5 tests=BAYES_00=-1.9, FREEMAIL_FROM=0.001, T_TO_NO_BRKTS_FREEMAIL=0.01 X-Spam-Level: X-Archive-Number: 201110/79 X-Sequence-Number: 35963 I have a table that stores a very large starting number called = epc_start_numeric and a quantity. I've apparently built the most = inefficient query possible for doing the job I need: find out if any = records overlap. Imagine the epc_start_numeric + quantity representing = a block of numbers. I need to find out if any of these blocks overlap. Here is the table: CREATE TABLE ftp_epc_audit ( record_id serial NOT NULL, sent_filename text NOT NULL, pcid text NOT NULL, tsid text NOT NULL, user_sec_id text NOT NULL, format_set text NOT NULL, format text NOT NULL, epc_start text NOT NULL, quantity integer, epc_decimal_start numeric(29) ) WITH OIDS; ALTER TABLE ftp_epc_audit OWNER TO postgres; And the query is currently this: SELECT '', 0, a.*, '', 0, b.* FROM ftp_epc_audit_staging a, ftp_epc_audit_staging b WHERE a.sent_filename <> b.sent_filename AND a.quantity > 0 AND b.quantity > 0 AND a.locked =3D 1 AND b.locked =3D 1 AND(( a.epc_decimal_start BETWEEN b.epc_decimal_start AND = b.epc_decimal_start + b.quantity - 1 ) OR ( a.epc_decimal_start + a.quantity - 1 BETWEEN b.epc_decimal_start = AND b.quantity - 1 ) OR ( a.epc_decimal_start + a.quantity - 1 < b.epc_decimal_start AND = a.epc_decimal_start + a.quantity -1 > b.epc_decimal_start + b.quantity - = 1 )) The column sent_filename is the unique value used so that a record does = not find itself. I've got an index on sent_filename, quantity, locked = and epc_decimal_start. The query runs fine with a very small number of records. However, I = need to process 60,000 records and this is taking hours. There must be = a fundemental flaw in either the query or my overall design because it = doesn't seem like a challenging task. =20 I've also tried a variant of this query which also takes several hours = to run through 60,000 records. SELECT * FROM ftp_epc_audit_staging a WHERE a.quantity > 0 AND a.locked =3D 1 AND EXISTS ( SELECT TRUE FROM ftp_epc_audit_staging b WHERE b.locked =3D = 1 AND b.quantity > 0 AND a.sent_filename <> b.sent_filename AND(( a.epc_decimal_start BETWEEN b.epc_decimal_start AND = b.epc_decimal_start + b.quantity - 1 ) OR ( a.epc_decimal_start + a.quantity - 1 BETWEEN b.epc_decimal_start = AND b.quantity - 1 ) OR ( a.epc_decimal_start + a.quantity - 1 < b.epc_decimal_start AND = a.epc_decimal_start + a.quantity -1 > b.epc_decimal_start + b.quantity - = 1 ))) I would really appreciate any thoughts on this.=