X-Original-To: pgsql-performance-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id AC6E211F6225 for ; Wed, 5 Apr 2006 08:24:46 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 61096-02 for ; Wed, 5 Apr 2006 08:24:45 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey- Received: from peufeu.com (boutiquenumerique.com [82.67.9.10]) by postgresql.org (Postfix) with ESMTP id C458C11F623C for ; Wed, 5 Apr 2006 08:24:41 -0300 (ADT) Received: (qmail 11304 invoked from network); 5 Apr 2006 13:25:06 +0200 Received: from boutiquenumerique.com (HELO apollo13) (82.67.9.10) by boutiquenumerique.com with SMTP; 5 Apr 2006 13:25:06 +0200 To: Andrus , pgsql-performance@postgresql.org Subject: Re: Query runs too long for indexed tables References: <1144180128.32266.56.camel@state.g2switchworks.com> Message-ID: Date: Wed, 05 Apr 2006 13:25:05 +0200 From: PFC Content-Type: text/plain; format=flowed; delsp=yes; charset=utf-8 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Opera M2/8.51 (Linux, build 1462) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.408 required=5 tests=[AWL=-0.183, UPPERCASE_50_75=0.591] X-Spam-Score: 0.408 X-Spam-Level: X-Archive-Number: 200604/58 X-Sequence-Number: 18142 > outer joins are not supported in Postgres UPDATE command. True (and sad). You can try the following script to play with the various options : DROP TABLE one; DROP TABLE two; CREATE TABLE one (a SERIAL PRIMARY KEY, b INT NULL); CREATE TABLE two (b INT NOT NULL PRIMARY KEY); INSERT INTO two (b) SELECT x*2 FROM generate_series( 1, 50000 ) AS x; INSERT INTO one (b) SELECT x FROM generate_series( 1, 100000 ) AS x; EXPLAIN ANALYZE SELECT count(*) FROM one LEFT JOIN two ON one.b=two.b WHERE two.b IS NULL; --Try with and without... --CREATE INDEX one_b ON one(b); VACUUM ANALYZE one; VACUUM ANALYZE two; EXPLAIN ANALYZE SELECT count(*) FROM one LEFT JOIN two ON one.b=two.b WHERE two.b IS NULL; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=NULL WHERE b NOT IN (SELECT b FROM two ); SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=NULL WHERE b IN (SELECT one.b FROM one LEFT JOIN two ON one.b=two.b WHERE two.b IS NULL); SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=NULL FROM one x LEFT JOIN two ON x.b=two.b WHERE two.b IS NULL AND one.a=x.a; SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=NULL FROM one x LEFT JOIN two ON x.b=two.b WHERE two.b IS NULL AND one.b=x.b; SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=(SELECT two.b FROM two WHERE two.b=one.b); SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; EXPLAIN ANALYZE UPDATE one SET b=NULL WHERE NOT EXISTS (SELECT 1 FROM two WHERE two.b = one.b); SELECT * FROM one ORDER BY a LIMIT 5; ROLLBACK; VACUUM one; BEGIN; CREATE TABLE tmp AS SELECT one.a, two.b FROM one LEFT JOIN two ON one.b=two.b; SELECT * FROM tmp ORDER BY a LIMIT 5; DROP TABLE one; ALTER TABLE tmp RENAME TO one; ROLLBACK;