Re: Poor plan when joining against a union containing a join - Mailing list pgsql-performance

From Tom Lane
Subject Re: Poor plan when joining against a union containing a join
Date
Msg-id 3739.1362682022@sss.pgh.pa.us
Whole thread Raw
In response to Re: Poor plan when joining against a union containing a join  (David Leverton <levertond@googlemail.com>)
Responses Re: Poor plan when joining against a union containing a join  (David Leverton <levertond@googlemail.com>)
List pgsql-performance
David Leverton <levertond@googlemail.com> writes:
> On 7 March 2013 05:52, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> Josh Berkus <josh@agliodbs.com> writes:
>>> Actually, in case #4, Postgres *is* pushing down the join qual into the
>>> segments of the Union.

>> Yeah, but not further.  I believe the core issue here (as of 9.2) is
>> that we're not willing to generate parameterized paths for subquery
>> relations.  We could do that without a huge amount of new code,
>> I think, but the scary thing is how much time it might take to generate
>> (and then discard most of the) plans for assorted parameterizations of
>> complicated subqueries.

> Thanks for looking at this, both of you.

> Does "as of 9.2" mean it's better in 9.3?

No, I meant it was worse before 9.2 --- previous versions weren't even
theoretically capable of generating the plan shape you want.  What
you're after is for the sub-join to be treated as a parameterized
sub-plan, and we did not have any ability to do that for anything more
complicated than a single-relation scan.

> I do intend to upgrade once
> it's released, so if it can handle this better (or if there's anything
> that can be done to improve it between now and then without making
> other things worse) that would be great.  Otherwise, I'm wondering if
> the addition of LATERAL will help persuade the planner to do what I
> want, something like this, perhaps?

Good idea, but no such luck in that form: it's still not going to try to
push the parameterization down into the sub-query.  I think you'd have
to write out the query with the views expanded and manually put the
WHERE restrictions into the lowest join level.  [ experiments... ]
Looks like only the UNION view has to be manually expanded to get a
good plan with HEAD:

regression=# explain SELECT *
     FROM item_reference,
         LATERAL (
           SELECT item_id_a, item_id_b FROM bundled_item WHERE (item_id_a, item_id_b)
                 = (item_reference.item_id_a, item_reference.item_id_b)
           UNION ALL
           SELECT item_id_a, item_id_b FROM unbundled_item WHERE (item_id_a, item_id_b)
                 = (item_reference.item_id_a, item_reference.item_id_b)
         ) item
     WHERE reference_id = 1;
                                                  QUERY PLAN
---------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=0.57..25.99 rows=2 width=20)
   ->  Seq Scan on item_reference  (cost=0.00..1.02 rows=1 width=12)
         Filter: (reference_id = 1)
   ->  Append  (cost=0.57..24.94 rows=2 width=8)
         ->  Nested Loop  (cost=0.57..16.61 rows=1 width=8)
               Join Filter: (bundle.bundle_type = bundle_contents.bundle_type)
               ->  Index Scan using bundle_pkey on bundle  (cost=0.29..8.31 rows=1 width=8)
                     Index Cond: (bundle_id = item_reference.item_id_a)
               ->  Index Scan using bundle_contents_pkey on bundle_contents  (cost=0.28..8.29 rows=1 width=8)
                     Index Cond: (item_id = item_reference.item_id_b)
         ->  Index Only Scan using unbundled_item_pkey on unbundled_item  (cost=0.29..8.31 rows=1 width=8)
               Index Cond: ((item_id_a = item_reference.item_id_a) AND (item_id_b = item_reference.item_id_b))
(12 rows)


You might be able to accomplish something similar without LATERAL, if
you're willing to give up the notational convenience of the views.
Don't have time right now to experiment further though.

            regards, tom lane


pgsql-performance by date:

Previous
From: David Leverton
Date:
Subject: Re: Poor plan when joining against a union containing a join
Next
From: CSS
Date:
Subject: Anyone running Intel S3700 SSDs?