diff options
| author | Alvaro Herrera | 2018-06-26 14:35:26 +0000 |
|---|---|---|
| committer | Alvaro Herrera | 2018-06-26 14:35:26 +0000 |
| commit | 7d872c91a3f9d49b56117557cdbb0c3d4c620687 (patch) | |
| tree | 4625ac6dcba79056ffd04adc01c3a50409452255 /src/include | |
| parent | 6ca33a885bf892a7fa34020a2620c83ccec3cdd7 (diff) | |
Allow direct lookups of AppendRelInfo by child relid
find_appinfos_by_relids had quite a large overhead when the number of
items in the append_rel_list was high, as it had to trawl through the
append_rel_list looking for AppendRelInfos belonging to the given
childrelids. Since there can only be a single AppendRelInfo for each
child rel, it seems much better to store an array in PlannerInfo which
indexes these by child relid, making the function O(1) rather than O(N).
This function was only called once inside the planner, so just replace
that call with a lookup to the new array. find_childrel_appendrelinfo
is now unused and thus removed.
This fixes a planner performance regression new to v11 reported by
Thomas Reiss.
Author: David Rowley
Reported-by: Thomas Reiss
Reviewed-by: Ashutosh Bapat
Reviewed-by: Álvaro Herrera
Discussion: https://postgr.es/m/94dd7a4b-5e50-0712-911d-2278e055c622@dalibo.com
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/nodes/relation.h | 10 | ||||
| -rw-r--r-- | src/include/optimizer/pathnode.h | 3 |
2 files changed, 11 insertions, 2 deletions
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index 5af484024ae..346cf089367 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -162,6 +162,8 @@ typedef struct PlannerGlobal * the passed-in Query data structure; someday that should stop. *---------- */ +struct AppendRelInfo; + typedef struct PlannerInfo { NodeTag type; @@ -202,6 +204,14 @@ typedef struct PlannerInfo RangeTblEntry **simple_rte_array; /* rangetable as an array */ /* + * append_rel_list is the same length as the above arrays, and holds + * pointers to the corresponding AppendRelInfo entry indexed by + * child_relid, or NULL if none. The array itself is not allocated if + * append_rel_list is empty. + */ + struct AppendRelInfo **append_rel_array; + + /* * all_baserels is a Relids set of all base relids (but not "other" * relids) in the query; that is, the Relids identifier of the final join * we need to form. This is computed in make_one_rel, just before we diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h index e99ae36befb..4ba358e72dc 100644 --- a/src/include/optimizer/pathnode.h +++ b/src/include/optimizer/pathnode.h @@ -261,6 +261,7 @@ extern Path *reparameterize_path_by_child(PlannerInfo *root, Path *path, * prototypes for relnode.c */ extern void setup_simple_rel_arrays(PlannerInfo *root); +extern void setup_append_rel_array(PlannerInfo *root); extern RelOptInfo *build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent); extern RelOptInfo *find_base_rel(PlannerInfo *root, int relid); @@ -278,8 +279,6 @@ extern Relids min_join_parameterization(PlannerInfo *root, extern RelOptInfo *build_empty_join_rel(PlannerInfo *root); extern RelOptInfo *fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids); -extern AppendRelInfo *find_childrel_appendrelinfo(PlannerInfo *root, - RelOptInfo *rel); extern Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel); extern ParamPathInfo *get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel, |
