mirror of
https://github.com/postgres/postgres.git
synced 2025-11-21 00:42:43 +03:00
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
This commit is contained in:
@@ -166,6 +166,12 @@ plan_set_operations(PlannerInfo *root)
|
||||
*/
|
||||
setup_simple_rel_arrays(root);
|
||||
|
||||
/*
|
||||
* Populate append_rel_array with each AppendRelInfo to allow direct
|
||||
* lookups by child relid.
|
||||
*/
|
||||
setup_append_rel_array(root);
|
||||
|
||||
/*
|
||||
* Find the leftmost component Query. We need to use its column names for
|
||||
* all generated tlists (else SELECT INTO won't work right).
|
||||
@@ -2617,29 +2623,22 @@ build_child_join_sjinfo(PlannerInfo *root, SpecialJoinInfo *parent_sjinfo,
|
||||
AppendRelInfo **
|
||||
find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)
|
||||
{
|
||||
ListCell *lc;
|
||||
AppendRelInfo **appinfos;
|
||||
int cnt = 0;
|
||||
int i;
|
||||
|
||||
*nappinfos = bms_num_members(relids);
|
||||
appinfos = (AppendRelInfo **) palloc(sizeof(AppendRelInfo *) * *nappinfos);
|
||||
|
||||
foreach(lc, root->append_rel_list)
|
||||
i = -1;
|
||||
while ((i = bms_next_member(relids, i)) >= 0)
|
||||
{
|
||||
AppendRelInfo *appinfo = lfirst(lc);
|
||||
AppendRelInfo *appinfo = root->append_rel_array[i];
|
||||
|
||||
if (bms_is_member(appinfo->child_relid, relids))
|
||||
{
|
||||
appinfos[cnt] = appinfo;
|
||||
cnt++;
|
||||
if (!appinfo)
|
||||
elog(ERROR, "child rel %d not found in append_rel_array", i);
|
||||
|
||||
/* Stop when we have gathered all the AppendRelInfos. */
|
||||
if (cnt == *nappinfos)
|
||||
return appinfos;
|
||||
}
|
||||
appinfos[cnt++] = appinfo;
|
||||
}
|
||||
|
||||
/* Should have found the entries ... */
|
||||
elog(ERROR, "did not find all requested child rels in append_rel_list");
|
||||
return NULL; /* not reached */
|
||||
return appinfos;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user