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

Commitafcf09d

Browse files
committed
Some further performance tweaks for planning large inheritance trees that
are mostly excluded by constraints: do the CE test a bit earlier to savesome adjust_appendrel_attrs() work on excluded children, and arrange touse array indexing rather than rt_fetch() to fetch RTEs in the main bodyof the planner. The latter is something I'd wanted to do for awhile anyway,but seeing list_nth_cell() as 35% of the runtime gets one's attention.
1 parentac7e6c0 commitafcf09d

File tree

11 files changed

+91
-42
lines changed

11 files changed

+91
-42
lines changed

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

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.162 2007/04/2106:18:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.163 2007/04/2121:01:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -39,7 +39,8 @@ intgeqo_threshold;
3939

4040

4141
staticvoidset_base_rel_pathlists(PlannerInfo*root);
42-
staticvoidset_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,Indexrti);
42+
staticvoidset_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,
43+
Indexrti,RangeTblEntry*rte);
4344
staticvoidset_plain_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,
4445
RangeTblEntry*rte);
4546
staticvoidset_append_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,
@@ -144,7 +145,7 @@ set_base_rel_pathlists(PlannerInfo *root)
144145
if (rel->reloptkind!=RELOPT_BASEREL)
145146
continue;
146147

147-
set_rel_pathlist(root,rel,rti);
148+
set_rel_pathlist(root,rel,rti,root->simple_rte_array[rti]);
148149
}
149150
}
150151

@@ -153,10 +154,9 @@ set_base_rel_pathlists(PlannerInfo *root)
153154
* Build access paths for a base relation
154155
*/
155156
staticvoid
156-
set_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,Indexrti)
157+
set_rel_pathlist(PlannerInfo*root,RelOptInfo*rel,
158+
Indexrti,RangeTblEntry*rte)
157159
{
158-
RangeTblEntry*rte=rt_fetch(rti,root->parse->rtable);
159-
160160
if (rte->inh)
161161
{
162162
/* It's an "append relation", process accordingly */
@@ -200,8 +200,11 @@ set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
200200
* If we can prove we don't need to scan the rel via constraint exclusion,
201201
* set up a single dummy path for it. (Rather than inventing a special
202202
* "dummy" path type, we represent this as an AppendPath with no members.)
203+
* We only need to check for regular baserels; if it's an otherrel, CE
204+
* was already checked in set_append_rel_pathlist().
203205
*/
204-
if (relation_excluded_by_constraints(rel,rte))
206+
if (rel->reloptkind==RELOPT_BASEREL&&
207+
relation_excluded_by_constraints(rel,rte))
205208
{
206209
/* Set dummy size estimates --- we leave attr_widths[] as zeroes */
207210
rel->rows=0;
@@ -294,6 +297,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
294297
{
295298
AppendRelInfo*appinfo= (AppendRelInfo*)lfirst(l);
296299
intchildRTindex;
300+
RangeTblEntry*childRTE;
297301
RelOptInfo*childrel;
298302
Path*childpath;
299303
ListCell*parentvars;
@@ -304,6 +308,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
304308
continue;
305309

306310
childRTindex=appinfo->child_relid;
311+
childRTE=root->simple_rte_array[childRTindex];
307312

308313
/*
309314
* The child rel's RelOptInfo was already created during
@@ -313,18 +318,29 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
313318
Assert(childrel->reloptkind==RELOPT_OTHER_MEMBER_REL);
314319

315320
/*
316-
* Copy the parent's targetlist and quals to the child, with
317-
* appropriate substitution of variables.
321+
* We have to copy the parent's targetlist and quals to the child,
322+
* with appropriate substitution of variables. However, only the
323+
* baserestrictinfo quals are needed before we can check for
324+
* constraint exclusion; so do that first and then check to see
325+
* if we can disregard this child.
318326
*/
319-
childrel->reltargetlist= (List*)
320-
adjust_appendrel_attrs((Node*)rel->reltargetlist,
321-
appinfo);
322327
childrel->baserestrictinfo= (List*)
323328
adjust_appendrel_attrs((Node*)rel->baserestrictinfo,
324329
appinfo);
330+
331+
if (relation_excluded_by_constraints(childrel,childRTE))
332+
{
333+
/* this child need not be scanned, so just disregard it */
334+
continue;
335+
}
336+
337+
/* CE failed, so finish copying targetlist and join quals */
325338
childrel->joininfo= (List*)
326339
adjust_appendrel_attrs((Node*)rel->joininfo,
327340
appinfo);
341+
childrel->reltargetlist= (List*)
342+
adjust_appendrel_attrs((Node*)rel->reltargetlist,
343+
appinfo);
328344

329345
/*
330346
* We have to make child entries in the EquivalenceClass data
@@ -353,12 +369,9 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
353369
* It's possible that the child is itself an appendrel, in which case
354370
* we can "cut out the middleman" and just add its child paths to our
355371
* own list. (We don't try to do this earlier because we need to
356-
* apply both levels of transformation to the quals.) This test also
357-
* handles the case where the child rel need not be scanned because of
358-
* constraint exclusion: it'll have an Append path with no subpaths,
359-
* and will vanish from our list.
372+
* apply both levels of transformation to the quals.)
360373
*/
361-
set_rel_pathlist(root,childrel,childRTindex);
374+
set_rel_pathlist(root,childrel,childRTindex,childRTE);
362375

363376
childpath=childrel->cheapest_total_path;
364377
if (IsA(childpath,AppendPath))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.84 2007/02/19 07:03:28 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.85 2007/04/21 21:01:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -500,7 +500,7 @@ clause_selectivity(PlannerInfo *root,
500500
if (var->varlevelsup==0&&
501501
(varRelid==0||varRelid== (int)var->varno))
502502
{
503-
RangeTblEntry*rte=rt_fetch(var->varno,root->parse->rtable);
503+
RangeTblEntry*rte=planner_rt_fetch(var->varno,root);
504504

505505
if (rte->rtekind==RTE_SUBQUERY)
506506
{

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
* Portions Copyright (c) 1994, Regents of the University of California
5555
*
5656
* IDENTIFICATION
57-
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.180 2007/04/2102:41:13 tgl Exp $
57+
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.181 2007/04/2121:01:44 tgl Exp $
5858
*
5959
*-------------------------------------------------------------------------
6060
*/
@@ -856,7 +856,7 @@ cost_functionscan(Path *path, PlannerInfo *root, RelOptInfo *baserel)
856856

857857
/* Should only be applied to base relations that are functions */
858858
Assert(baserel->relid>0);
859-
rte=rt_fetch(baserel->relid,root->parse->rtable);
859+
rte=planner_rt_fetch(baserel->relid,root);
860860
Assert(rte->rtekind==RTE_FUNCTION);
861861

862862
/* Estimate costs of executing the function expression */
@@ -2297,7 +2297,7 @@ set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel)
22972297

22982298
/* Should only be applied to base relations that are functions */
22992299
Assert(rel->relid>0);
2300-
rte=rt_fetch(rel->relid,root->parse->rtable);
2300+
rte=planner_rt_fetch(rel->relid,root);
23012301
Assert(rte->rtekind==RTE_FUNCTION);
23022302

23032303
/* Estimate number of rows the function itself will return */
@@ -2323,7 +2323,7 @@ set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel)
23232323

23242324
/* Should only be applied to base relations that are values lists */
23252325
Assert(rel->relid>0);
2326-
rte=rt_fetch(rel->relid,root->parse->rtable);
2326+
rte=planner_rt_fetch(rel->relid,root);
23272327
Assert(rte->rtekind==RTE_VALUES);
23282328

23292329
/*

‎src/backend/optimizer/plan/createplan.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.228 2007/04/06 22:33:42 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.229 2007/04/21 21:01:44 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1353,7 +1353,7 @@ create_functionscan_plan(PlannerInfo *root, Path *best_path,
13531353

13541354
/* it should be a function base rel... */
13551355
Assert(scan_relid>0);
1356-
rte=rt_fetch(scan_relid,root->parse->rtable);
1356+
rte=planner_rt_fetch(scan_relid,root);
13571357
Assert(rte->rtekind==RTE_FUNCTION);
13581358

13591359
/* Sort clauses into best execution order */
@@ -1388,7 +1388,7 @@ create_valuesscan_plan(PlannerInfo *root, Path *best_path,
13881388

13891389
/* it should be a values base rel... */
13901390
Assert(scan_relid>0);
1391-
rte=rt_fetch(scan_relid,root->parse->rtable);
1391+
rte=planner_rt_fetch(scan_relid,root);
13921392
Assert(rte->rtekind==RTE_VALUES);
13931393

13941394
/* Sort clauses into best execution order */

‎src/backend/optimizer/plan/planagg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.30 2007/03/17 00:11:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.31 2007/04/21 21:01:45 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -116,7 +116,7 @@ optimize_minmax_aggregates(PlannerInfo *root, List *tlist, Path *best_path)
116116
if (!IsA(jtnode,RangeTblRef))
117117
returnNULL;
118118
rtr= (RangeTblRef*)jtnode;
119-
rte=rt_fetch(rtr->rtindex,parse->rtable);
119+
rte=planner_rt_fetch(rtr->rtindex,root);
120120
if (rte->rtekind!=RTE_RELATION||rte->inh)
121121
returnNULL;
122122
rel=find_base_rel(root,rtr->rtindex);

‎src/backend/optimizer/plan/planmain.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*
1515
*
1616
* IDENTIFICATION
17-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.99 2007/01/20 20:45:39 tgl Exp $
17+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.100 2007/04/21 21:01:45 tgl Exp $
1818
*
1919
*-------------------------------------------------------------------------
2020
*/
@@ -86,6 +86,7 @@ query_planner(PlannerInfo *root, List *tlist, double tuple_fraction,
8686
Path*cheapestpath;
8787
Path*sortedpath;
8888
Indexrti;
89+
ListCell*lc;
8990
doubletotal_pages;
9091

9192
/* Make tuple_fraction accessible to lower-level routines */
@@ -123,6 +124,20 @@ query_planner(PlannerInfo *root, List *tlist, double tuple_fraction,
123124
root->full_join_clauses=NIL;
124125
root->oj_info_list=NIL;
125126

127+
/*
128+
* Make a flattened version of the rangetable for faster access (this
129+
* is OK because the rangetable won't change any more).
130+
*/
131+
root->simple_rte_array= (RangeTblEntry**)
132+
palloc0(root->simple_rel_array_size*sizeof(RangeTblEntry*));
133+
rti=1;
134+
foreach(lc,parse->rtable)
135+
{
136+
RangeTblEntry*rte= (RangeTblEntry*)lfirst(lc);
137+
138+
root->simple_rte_array[rti++]=rte;
139+
}
140+
126141
/*
127142
* Construct RelOptInfo nodes for all base relations in query, and
128143
* indirectly for all appendrel member relations ("other rels"). This

‎src/backend/optimizer/util/pathnode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.138 2007/02/06 02:59:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.139 2007/04/21 21:01:45 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -800,7 +800,7 @@ create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath)
800800
*/
801801
if (sub_targetlist&&rel->rtekind==RTE_SUBQUERY)
802802
{
803-
RangeTblEntry*rte=rt_fetch(rel->relid,root->parse->rtable);
803+
RangeTblEntry*rte=planner_rt_fetch(rel->relid,root);
804804
List*sub_tlist_colnos;
805805

806806
sub_tlist_colnos=translate_sub_tlist(sub_targetlist,rel->relid);

‎src/backend/optimizer/util/plancat.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.133 2007/04/06 22:33:42 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.134 2007/04/21 21:01:45 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -497,6 +497,9 @@ get_relation_constraints(Oid relationObjectId, RelOptInfo *rel)
497497
* Detect whether the relation need not be scanned because it has either
498498
* self-inconsistent restrictions, or restrictions inconsistent with the
499499
* relation's CHECK constraints.
500+
*
501+
* Note: this examines only rel->relid and rel->baserestrictinfo; therefore
502+
* it can be called before filling in other fields of the RelOptInfo.
500503
*/
501504
bool
502505
relation_excluded_by_constraints(RelOptInfo*rel,RangeTblEntry*rte)
@@ -595,7 +598,7 @@ build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
595598
{
596599
List*tlist=NIL;
597600
Indexvarno=rel->relid;
598-
RangeTblEntry*rte=rt_fetch(varno,root->parse->rtable);
601+
RangeTblEntry*rte=planner_rt_fetch(varno,root);
599602
Relationrelation;
600603
Query*subquery;
601604
Var*var;

‎src/backend/optimizer/util/relnode.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/relnode.c,v 1.86 2007/02/22 22:00:25 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/relnode.c,v 1.87 2007/04/21 21:01:45 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -56,15 +56,15 @@ build_simple_rel(PlannerInfo *root, int relid, RelOptKind reloptkind)
5656
RelOptInfo*rel;
5757
RangeTblEntry*rte;
5858

59-
/* Fetch RTE for relation */
60-
Assert(relid>0&&relid <=list_length(root->parse->rtable));
61-
rte=rt_fetch(relid,root->parse->rtable);
62-
6359
/* Rel should not exist already */
64-
Assert(relid<root->simple_rel_array_size);
60+
Assert(relid>0&&relid<root->simple_rel_array_size);
6561
if (root->simple_rel_array[relid]!=NULL)
6662
elog(ERROR,"rel %d already exists",relid);
6763

64+
/* Fetch RTE for relation */
65+
rte=root->simple_rte_array[relid];
66+
Assert(rte!=NULL);
67+
6868
rel=makeNode(RelOptInfo);
6969
rel->reloptkind=reloptkind;
7070
rel->relids=bms_make_singleton(relid);

‎src/backend/utils/adt/selfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.232 2007/04/06 22:33:42 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.233 2007/04/21 21:01:45 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -3487,7 +3487,7 @@ examine_variable(PlannerInfo *root, Node *node, int varRelid,
34873487
vardata->atttype=var->vartype;
34883488
vardata->atttypmod=var->vartypmod;
34893489

3490-
rte=rt_fetch(var->varno,root->parse->rtable);
3490+
rte=root->simple_rte_array[var->varno];
34913491

34923492
if (rte->inh)
34933493
{

‎src/include/nodes/relation.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.140 2007/04/06 22:33:43 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.141 2007/04/21 21:01:45 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -108,6 +108,14 @@ typedef struct PlannerInfo
108108
structRelOptInfo**simple_rel_array;/* All 1-rel RelOptInfos */
109109
intsimple_rel_array_size;/* allocated size of array */
110110

111+
/*
112+
* simple_rte_array is the same length as simple_rel_array and holds
113+
* pointers to the associated rangetable entries. This lets us avoid
114+
* rt_fetch(), which can be a bit slow once large inheritance sets have
115+
* been expanded.
116+
*/
117+
RangeTblEntry**simple_rte_array;/* rangetable as an array */
118+
111119
/*
112120
* join_rel_list is a list of all join-relation RelOptInfos we have
113121
* considered in this planning run. For small problems we just scan the
@@ -167,6 +175,16 @@ typedef struct PlannerInfo
167175
}PlannerInfo;
168176

169177

178+
/*
179+
* In places where it's known that simple_rte_array[] must have been prepared
180+
* already, we just index into it to fetch RTEs. In code that might be
181+
* executed before or after entering query_planner(), use this macro.
182+
*/
183+
#defineplanner_rt_fetch(rti,root) \
184+
((root)->simple_rte_array ? (root)->simple_rte_array[rti] : \
185+
rt_fetch(rti, (root)->parse->rtable))
186+
187+
170188
/*----------
171189
* RelOptInfo
172190
*Per-relation information for planning/optimization

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp