Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit77387f0

Browse files
committed
Suppress creation of backwardly-indexed paths for LATERAL join clauses.
Given a query such asSELECT * FROM foo JOIN LATERAL (SELECT foo.var1) ss(x) ON ss.x = foo.var2the existence of the join clause "ss.x = foo.var2" encourages indxpath.c tobuild a parameterized path for foo using any index available for foo.var2.This is completely useless activity, though, since foo has got to be on theoutside not the inside of any nestloop join with ss. It's reasonablyinexpensive to add tests that prevent creation of such paths, so let's dothat.
1 parent35738b5 commit77387f0

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

‎src/backend/optimizer/path/equivclass.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1969,11 +1969,15 @@ mutate_eclass_expressions(PlannerInfo *root,
19691969
* is no value in using more than one.(But it *is* worthwhile to create
19701970
* a separate parameterized path for each one, since that leads to different
19711971
* join orders.)
1972+
*
1973+
* The caller can pass a Relids set of rels we aren't interested in joining
1974+
* to, so as to save the work of creating useless clauses.
19721975
*/
19731976
List*
19741977
generate_implied_equalities_for_indexcol(PlannerInfo*root,
19751978
IndexOptInfo*index,
1976-
intindexcol)
1979+
intindexcol,
1980+
Relidsprohibited_rels)
19771981
{
19781982
List*result=NIL;
19791983
RelOptInfo*rel=index->rel;
@@ -2050,6 +2054,10 @@ generate_implied_equalities_for_indexcol(PlannerInfo *root,
20502054
bms_overlap(other_em->em_relids,rel->relids))
20512055
continue;
20522056

2057+
/* Forget it if caller doesn't want joins to this rel */
2058+
if (bms_overlap(other_em->em_relids,prohibited_rels))
2059+
continue;
2060+
20532061
/*
20542062
* Also, if this is a child rel, avoid generating a useless join
20552063
* to its parent rel.

‎src/backend/optimizer/path/indxpath.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,12 @@ static void match_restriction_clauses_to_index(RelOptInfo *rel,
121121
IndexClauseSet*clauseset);
122122
staticvoidmatch_join_clauses_to_index(PlannerInfo*root,
123123
RelOptInfo*rel,IndexOptInfo*index,
124+
Relidslateral_referencers,
124125
IndexClauseSet*clauseset,
125126
List**joinorclauses);
126127
staticvoidmatch_eclass_clauses_to_index(PlannerInfo*root,
127128
IndexOptInfo*index,
129+
Relidslateral_referencers,
128130
IndexClauseSet*clauseset);
129131
staticvoidmatch_clauses_to_index(IndexOptInfo*index,
130132
List*clauses,
@@ -211,22 +213,40 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
211213
List*bitindexpaths;
212214
List*bitjoinpaths;
213215
List*joinorclauses;
216+
Relidslateral_referencers;
214217
IndexClauseSetrclauseset;
215218
IndexClauseSetjclauseset;
216219
IndexClauseSeteclauseset;
217-
ListCell*ilist;
220+
ListCell*lc;
218221

219222
/* Skip the whole mess if no indexes */
220223
if (rel->indexlist==NIL)
221224
return;
222225

226+
/*
227+
* If there are any rels that have LATERAL references to this one, we
228+
* cannot use join quals referencing them as index quals for this one,
229+
* since such rels would have to be on the inside not the outside of a
230+
* nestloop join relative to this one. Create a Relids set listing all
231+
* such rels, for use in checks of potential join clauses.
232+
*/
233+
lateral_referencers=NULL;
234+
foreach(lc,root->lateral_info_list)
235+
{
236+
LateralJoinInfo*ljinfo= (LateralJoinInfo*)lfirst(lc);
237+
238+
if (bms_is_member(rel->relid,ljinfo->lateral_lhs))
239+
lateral_referencers=bms_add_member(lateral_referencers,
240+
ljinfo->lateral_rhs);
241+
}
242+
223243
/* Bitmap paths are collected and then dealt with at the end */
224244
bitindexpaths=bitjoinpaths=joinorclauses=NIL;
225245

226246
/* Examine each index in turn */
227-
foreach(ilist,rel->indexlist)
247+
foreach(lc,rel->indexlist)
228248
{
229-
IndexOptInfo*index= (IndexOptInfo*)lfirst(ilist);
249+
IndexOptInfo*index= (IndexOptInfo*)lfirst(lc);
230250

231251
/* Protect limited-size array in IndexClauseSets */
232252
Assert(index->ncolumns <=INDEX_MAX_KEYS);
@@ -260,15 +280,16 @@ create_index_paths(PlannerInfo *root, RelOptInfo *rel)
260280
* EquivalenceClasses.Also, collect join OR clauses for later.
261281
*/
262282
MemSet(&jclauseset,0,sizeof(jclauseset));
263-
match_join_clauses_to_index(root,rel,index,
283+
match_join_clauses_to_index(root,rel,index,lateral_referencers,
264284
&jclauseset,&joinorclauses);
265285

266286
/*
267287
* Look for EquivalenceClasses that can generate joinclauses matching
268288
* the index.
269289
*/
270290
MemSet(&eclauseset,0,sizeof(eclauseset));
271-
match_eclass_clauses_to_index(root,index,&eclauseset);
291+
match_eclass_clauses_to_index(root,index,lateral_referencers,
292+
&eclauseset);
272293

273294
/*
274295
* If we found any plain or eclass join clauses, decide what to do
@@ -1796,6 +1817,7 @@ match_restriction_clauses_to_index(RelOptInfo *rel, IndexOptInfo *index,
17961817
staticvoid
17971818
match_join_clauses_to_index(PlannerInfo*root,
17981819
RelOptInfo*rel,IndexOptInfo*index,
1820+
Relidslateral_referencers,
17991821
IndexClauseSet*clauseset,
18001822
List**joinorclauses)
18011823
{
@@ -1810,6 +1832,10 @@ match_join_clauses_to_index(PlannerInfo *root,
18101832
if (!join_clause_is_movable_to(rinfo,rel->relid))
18111833
continue;
18121834

1835+
/* Not useful if it conflicts with any LATERAL references */
1836+
if (bms_overlap(rinfo->clause_relids,lateral_referencers))
1837+
continue;
1838+
18131839
/* Potentially usable, so see if it matches the index or is an OR */
18141840
if (restriction_is_or_clause(rinfo))
18151841
*joinorclauses=lappend(*joinorclauses,rinfo);
@@ -1825,6 +1851,7 @@ match_join_clauses_to_index(PlannerInfo *root,
18251851
*/
18261852
staticvoid
18271853
match_eclass_clauses_to_index(PlannerInfo*root,IndexOptInfo*index,
1854+
Relidslateral_referencers,
18281855
IndexClauseSet*clauseset)
18291856
{
18301857
intindexcol;
@@ -1837,9 +1864,11 @@ match_eclass_clauses_to_index(PlannerInfo *root, IndexOptInfo *index,
18371864
{
18381865
List*clauses;
18391866

1867+
/* Generate clauses, skipping any that join to lateral_referencers */
18401868
clauses=generate_implied_equalities_for_indexcol(root,
18411869
index,
1842-
indexcol);
1870+
indexcol,
1871+
lateral_referencers);
18431872

18441873
/*
18451874
* We have to check whether the results actually do match the index,

‎src/include/optimizer/paths.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ extern void mutate_eclass_expressions(PlannerInfo *root,
127127
void*context);
128128
externList*generate_implied_equalities_for_indexcol(PlannerInfo*root,
129129
IndexOptInfo*index,
130-
intindexcol);
130+
intindexcol,
131+
Relidsprohibited_rels);
131132
externboolhave_relevant_eclass_joinclause(PlannerInfo*root,
132133
RelOptInfo*rel1,RelOptInfo*rel2);
133134
externboolhas_relevant_eclass_joinclause(PlannerInfo*root,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp