> 2015/03/25 19:09、Kouhei Kaigai <kai...@ak.jp.nec.com> のメール:
> 
> >> On Wed, Mar 25, 2015 at 3:14 PM, Shigeru HANADA <shigeru.han...@gmail.com>
> wrote:
> >>    Or bottom of make_join_rel().  IMO build_join_rel() is responsible for
> >> just building (or searching from a list) a RelOptInfo for given relids.  
> >> After
> >> that make_join_rel() calls add_paths_to_joinrel() with appropriate 
> >> arguments
> per
> >> join type to generate actual Paths implements the join.  make_join_rel() is
> >> called only once for particular relid combination, and there 
> >> SpecialJoinInfo
> and
> >> restrictlist (conditions specified in JOIN-ON and WHERE), so it seems 
> >> promising
> >> for FDW cases.
> >>
> >>
> >>
> >> I like that idea, but I think we will have complex hook signature, it won't
> remain
> >> as simple as hook (root, joinrel).
> >>
> > In this case, GetForeignJoinPaths() will take root, joinrel, rel1, rel2,
> > sjinfo and restrictlist.
> > It is not too simple, but not complicated signature.
> >
> > Even if we reconstruct rel1 and rel2 using sjinfo, we also need to compute
> > restrictlist using build_joinrel_restrictlist() again. It is a static 
> > function
> > in relnode.c. So, I don't think either of them has definitive advantage from
> > the standpoint of simplicity.
> 
> The bottom of make_join_rel() seems good from the viewpoint of information, 
> but
> it is called multiple times for join combinations which are essentially 
> identical,
> for INNER JOIN case like this:
> 
> fdw=# explain select * from pgbench_branches b join pgbench_tellers t on t.bid
> = b.bid join pgbench_accounts a on a.bid = b.bid and a.bid = t.bid;
> INFO:  postgresGetForeignJoinPaths() 1x2
> INFO:  postgresGetForeignJoinPaths() 1x4
> INFO:  postgresGetForeignJoinPaths() 2x4
> INFO:  standard_join_search() old hook point
> INFO:  standard_join_search() old hook point
> INFO:  standard_join_search() old hook point
> INFO:  postgresGetForeignJoinPaths() 0x4
> INFO:  postgresGetForeignJoinPaths() 0x2
> INFO:  postgresGetForeignJoinPaths() 0x1
> INFO:  standard_join_search() old hook point
>                        QUERY PLAN
> ---------------------------------------------------------
>  Foreign Scan  (cost=100.00..102.11 rows=211 width=1068)
> (1 row)
> 
> Here I’ve put probe point in the beginnig of GetForeignJoinPaths handler and 
> just
> before set_cheapest() call in standard_join_search() as “old hook point”.  In
> this example 1, 2, and 4 are base relations, and in the join level 3 planner 
> calls
> GetForeignJoinPaths() three times for the combinations:
> 
> 1) (1x2)x4
> 2) (1x4)x2
> 3) (2x4)x1
> 
> Tom’s suggestion is aiming at providing a chance to consider join push-down in
> more abstract level, IIUC.  So it would be good to call handler only once for
> that case, for flattened combination (1x2x3).
>
> Hum, how about skipping calling handler (or hook) if the joinrel was found by
> find_join_rel()?  At least it suppress redundant call for different join 
> orders,
> and handler can determine whether the combination can be flattened by checking
> that all RelOptInfo with RELOPT_JOINREL under joinrel has JOIN_INNER as 
> jointype.
> 
The reason why FDW handler was called multiple times on your example is,
your modified make_join_rel() does not check whether build_join_rel()
actually build a new RelOptInfo, or just a cache reference, doesn't it?

If so, I'm inclined to your proposition.
A new "bool *found" argument of build_join_rel() makes reduce number of
FDW handler call, with keeping reasonable information to build remote-
join query.

Thanks,
--
NEC OSS Promotion Center / PG-Strom Project
KaiGai Kohei <kai...@ak.jp.nec.com>


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to