]> granicus.if.org Git - postgresql/commitdiff
Tweak set_rel_width() to avoid redundant executions of getrelid().
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Apr 2007 02:41:13 +0000 (02:41 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 21 Apr 2007 02:41:13 +0000 (02:41 +0000)
In very large queries this accounts for a noticeable fraction of
planning time.  Per an example from Greg Stark.

src/backend/optimizer/path/costsize.c

index ff5bb7833727a95eb2eb28b9f35bd74b66a433d5..42a5520b974ebf0f0947923534e349f00be16d69 100644 (file)
@@ -54,7 +54,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * 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;
        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)
        {
                Var                *var = (Var *) lfirst(tllist);
                int                     ndx;
-               Oid                     relid;
+               Oid                     var_reloid;
                int32           item_width;
 
                /* For now, punt on whole-row child Vars */
@@ -2383,10 +2393,14 @@ set_rel_width(PlannerInfo *root, RelOptInfo *rel)
                        continue;
                }
 
-               relid = getrelid(var->varno, root->parse->rtable);
-               if (relid != InvalidOid)
+               if (var->varno == rel->relid)
+                       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)
                        {
                                rel->attr_widths[ndx] = item_width;