Tweak set_rel_width() to avoid redundant executions of getrelid().

In very large queries this accounts for a noticeable fraction of
planning time.  Per an example from Greg Stark.
This commit is contained in:
Tom Lane 2007-04-21 02:41:13 +00:00
parent 8073fff8e4
commit ca3d14f2a9

View File

@ -54,7 +54,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.179 2007/03/27 23:21:09 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.180 2007/04/21 02:41:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -2357,12 +2357,22 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
{ {
int32 tuple_width = 0; int32 tuple_width = 0;
ListCell *tllist; ListCell *tllist;
Oid rel_reloid;
/*
* Usually (perhaps always), all the Vars have the same reloid, so we can
* save some redundant list-searching by doing getrelid just once.
*/
if (rel->relid > 0)
rel_reloid = getrelid(rel->relid, root->parse->rtable);
else
rel_reloid = InvalidOid; /* probably can't happen */
foreach(tllist, rel->reltargetlist) foreach(tllist, rel->reltargetlist)
{ {
Var *var = (Var *) lfirst(tllist); Var *var = (Var *) lfirst(tllist);
int ndx; int ndx;
Oid relid; Oid var_reloid;
int32 item_width; int32 item_width;
/* For now, punt on whole-row child Vars */ /* For now, punt on whole-row child Vars */
@ -2383,10 +2393,14 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
continue; continue;
} }
relid = getrelid(var->varno, root->parse->rtable); if (var->varno == rel->relid)
if (relid != InvalidOid) var_reloid = rel_reloid;
else
var_reloid = getrelid(var->varno, root->parse->rtable);
if (var_reloid != InvalidOid)
{ {
item_width = get_attavgwidth(relid, var->varattno); item_width = get_attavgwidth(var_reloid, var->varattno);
if (item_width > 0) if (item_width > 0)
{ {
rel->attr_widths[ndx] = item_width; rel->attr_widths[ndx] = item_width;