Received: from makus.postgresql.org ([98.129.198.125]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1THiMO-0000sU-5i for pgsql-performance@postgresql.org; Fri, 28 Sep 2012 21:44:36 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1THiMM-0003hA-Nm for pgsql-performance@postgresql.org; Fri, 28 Sep 2012 21:44:35 +0000 Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.5/8.14.5) with ESMTP id q8SLiWCU016019; Fri, 28 Sep 2012 17:44:33 -0400 (EDT) From: Tom Lane To: Matt Daw cc: pgsql-performance@postgresql.org Subject: Re: Query plan, nested EXISTS In-reply-to: References: Comments: In-reply-to Matt Daw message dated "Fri, 28 Sep 2012 14:04:04 -0700" Date: Fri, 28 Sep 2012 17:44:32 -0400 Message-ID: <16018.1348868672@sss.pgh.pa.us> X-Pg-Spam-Score: -2.7 (--) X-Archive-Number: 201209/204 X-Sequence-Number: 47950 Matt Daw writes: > Howdy, I've been debugging a client's slow query today and I'm curious > about the query plan. It's picking a plan that hashes lots of rows from the > versions table (on v9.0.10)... > EXPLAIN ANALYZE > SELECT COUNT(*) FROM notes a WHERE > a.project_id = 114 AND > EXISTS ( > SELECT 1 FROM note_links b > WHERE > b.note_id = a.id AND > b.entity_type = 'Version' AND > EXISTS ( > SELECT 1 FROM versions c > WHERE > c.id = b.entity_id AND > c.code ILIKE '%comp%' AND > c.retirement_date IS NULL > ) AND > b.retirement_date IS NULL > ) I think the real problem here is that 9.0 is incapable of avoiding a full table scan on "note_links", which means it doesn't really have any better option than to do the inner EXISTS as a full-table semijoin. This is because it can't push a.id down through two levels of join, and because the semijoins don't commute, there's no way to get a.id into the scan of note_links to pull out only the useful rows. The hack with LIMIT avoids this problem by preventing the inner EXISTS from being treated as a full-fledged semijoin; but of course that hack leaves you vulnerable to very bad plans if the statistics are such that a nestloop join isn't the best bet for the inner EXISTS. The work I did for parameterized paths in 9.2 was intended to address exactly this type of scenario. I would be interested to know if 9.2 does this any better for you. regards, tom lane