Re: I want to make an example of using parameterized path

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: 高健 <luckyjackgao(at)gmail(dot)com>
Cc: Jeff Janes <jeff(dot)janes(at)gmail(dot)com>, pgsql-general <pgsql-general(at)postgresql(dot)org>
Subject: Re: I want to make an example of using parameterized path
Date: 2013-06-23 16:51:06
Message-ID: 18266.1372006266@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

=?UTF-8?B?6auY5YGl?= <luckyjackgao(at)gmail(dot)com> writes:
>>> So I think that the above example can not show that "parameterized path"
>>> has been created.

>> But if you try the PREPAREd sets in versions before 9.2, you will find
>> they use the same plan as each other. Allowing them to differ based on the
>> parameter they are executed with, just like the non-PREPARE ones differ, is
>> what parameterized paths is all about.

No, actually, parameterized paths have nothing to do with parameterized
queries. Here's a trivial example:

regression=# create table sml as select generate_series(1,1000000,100000) as x;
SELECT 10
regression=# analyze sml;
ANALYZE
regression=# create table big as select generate_series(1,1000000) as y;
SELECT 1000000
regression=# alter table big add primary key(y);
ALTER TABLE
regression=# analyze big;
ANALYZE
regression=# explain select * from sml, big where x=y;
QUERY PLAN
-------------------------------------------------------------------------------
Nested Loop (cost=0.42..85.65 rows=10 width=8)
-> Seq Scan on sml (cost=0.00..1.10 rows=10 width=4)
-> Index Only Scan using big_pkey on big (cost=0.42..8.45 rows=1 width=4)
Index Cond: (y = sml.x)
(4 rows)

The indexscan on "big" is a parameterized path (or was when it was still
inside the planner, anyway). It's parameterized by "sml.x", which is a
value that is not available from the "big" table so it has to be passed
in from the current outer row of a nestloop join.

Now, pre-9.2 PG versions were perfectly capable of generating plans that
looked just like that one, but the planner's method for doing so was a lot
more ad-hoc back then. The main practical benefit that we got from the
parameterized-path rewrite is that the planner can now generate plans
that require pushing an outer-row value down through more than one level
of join. For instance, consider this rather artificial example:

regression=# explain select * from sml left join (sml s2 join big on s2.x <= y) on big.y = sml.x;
QUERY PLAN
-------------------------------------------------------------------------------------
Nested Loop Left Join (cost=0.42..98.08 rows=33 width=12)
-> Seq Scan on sml (cost=0.00..1.10 rows=10 width=4)
-> Nested Loop (cost=0.42..9.67 rows=3 width=8)
Join Filter: (s2.x <= big.y)
-> Index Only Scan using big_pkey on big (cost=0.42..8.44 rows=1 width=4)
Index Cond: (y = sml.x)
-> Seq Scan on sml s2 (cost=0.00..1.10 rows=10 width=4)
(7 rows)

The joins have to be done in that order because the leftjoin and inner
join don't commute. So "sml.x" is being passed down through the inner
nestloop join. Pre-9.2 could not have found that plan, and would have
had to do something involving a full-table scan of "big".

regards, tom lane

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Noah Misch 2013-06-23 16:53:59 Re: BUG #7493: Postmaster messages unreadable in a Windows console
Previous Message Moshe Jacobson 2013-06-23 16:34:50 pg_restore order and check constraints