Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1ZTcOd-0000Yh-SE for pgsql-sql@arkaria.postgresql.org; Sun, 23 Aug 2015 21:01:43 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1ZTcOc-0006TY-KY for pgsql-sql@arkaria.postgresql.org; Sun, 23 Aug 2015 21:01:42 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1ZTcNe-0005P1-Ft for pgsql-sql@postgresql.org; Sun, 23 Aug 2015 21:00:42 +0000 Received: from arbun.splivalo.hr ([78.47.9.189]) by magus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1ZTcNX-0001aQ-MW for pgsql-sql@postgresql.org; Sun, 23 Aug 2015 21:00:41 +0000 Received: from [192.168.10.1] (cpe-188-129-105-100.dynamic.amis.hr [188.129.105.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: mario) by arbun.splivalo.hr (Postfix) with ESMTPSA id A34C6120329 for ; Sun, 23 Aug 2015 23:00:33 +0200 (CEST) Message-ID: <55DA348D.9050704@splivalo.hr> Date: Sun, 23 Aug 2015 23:01:01 +0200 From: Mario Splivalo User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.8.0 MIME-Version: 1.0 To: "pgsql-sql@postgresql.org" Subject: WHERE ... NOT NULL ... OR ... (SELECT...) Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -1.6 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org I have a query, like this: valipile=# explain select * from account_analytic_line where move_id in (SELECT id FROM account_move_line); QUERY PLAN --------------------------------------------------------------------------------------- Hash Semi Join (cost=60799.74..96694.82 rows=329568 width=162) Hash Cond: (account_analytic_line.move_id = account_move_line.id) -> Seq Scan on account_analytic_line (cost=0.00..9620.68 rows=329568 width=162) -> Hash (cost=41292.66..41292.66 rows=1188966 width=4) -> Seq Scan on account_move_line (cost=0.00..41292.66 rows=1188966 width=4) (5 rows) Which is all fine. However, as move_id in account_analytic_line is NULLable I want to include that one into my query. But then: valipile=# explain select * from account_analytic_line where move_id is null or move_id in (SELECT id FROM account_move_line); QUERY PLAN ----------------------------------------------------------------------------------------- Seq Scan on account_analytic_line (cost=0.00..9039221110.12 rows=164784 width=162) Filter: ((move_id IS NULL) OR (SubPlan 1)) SubPlan 1 -> Materialize (cost=0.00..51882.49 rows=1188966 width=4) -> Seq Scan on account_move_line (cost=0.00..41292.66 rows=1188966 width=4) (5 rows) This, of course, takes forever. (There are no indexes/constraints/whatever on the tables as I'm deleting old data from the database) Now, I did 'circumvent' the waiting with using UNION: valipile=# explain select * from account_analytic_line where move_id in (select id from account_move_line) union select * from account_analytic_line where move_id is null; --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Unique (cost=193891.55..212017.84 rows=329569 width=162) -> Sort (cost=193891.55..194715.47 rows=329569 width=162) Sort Key: account_analytic_line.id, account_analytic_line.create_uid, account_analytic_line.create_date, account_analytic_line.write_date, account_analytic_line.write_uid, account_analytic_line.amount, account_analytic_line.user_id, account_analy -> Append (cost=60799.74..109611.18 rows=329569 width=162) -> Hash Semi Join (cost=60799.74..96694.82 rows=329568 width=162) Hash Cond: (account_analytic_line.move_id = account_move_line.id) -> Seq Scan on account_analytic_line (cost=0.00..9620.68 rows=329568 width=162) -> Hash (cost=41292.66..41292.66 rows=1188966 width=4) -> Seq Scan on account_move_line (cost=0.00..41292.66 rows=1188966 width=4) -> Seq Scan on account_analytic_line account_analytic_line_1 (cost=0.00..9620.68 rows=1 width=162) Filter: (move_id IS NULL) (11 rows) but I'm curious why postgres chooses such poor query plan for the 'OR column IS NULL' addition ? Mario -- Mario Splivalo mario@splivalo.hr "I can do it quick, I can do it cheap, I can do it well. Pick any two." -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql