Allow the planner's estimate of the fraction of a cursor's rows that will be
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 2 May 2008 21:26:10 +0000 (21:26 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 2 May 2008 21:26:10 +0000 (21:26 +0000)
retrieved to be controlled through a GUC variable.

Robert Hell

doc/src/sgml/config.sgml
src/backend/optimizer/plan/planner.c
src/backend/utils/misc/guc.c
src/backend/utils/misc/postgresql.conf.sample
src/include/optimizer/planmain.h

index d650b80fb19c8a2f57a3bbe73470555fced45b03..d123059ad1b7b034b593ef223523ea2847427834 100644 (file)
@@ -2238,6 +2238,26 @@ SELECT * FROM parent WHERE key = 2400;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-cursor-tuple-fraction" xreflabel="cursor_tuple_fraction">
+      <term><varname>cursor_tuple_fraction</varname> (<type>floating point</type>)</term>
+      <indexterm>
+       <primary><varname>cursor_tuple_fraction</> configuration parameter</primary>
+      </indexterm>
+      <listitem>
+       <para>
+        Sets the planner's estimate of the fraction of a cursor's rows that
+        will be retrieved.  The default is 0.1.  Smaller values of this
+        setting bias the planner towards using <quote>fast start</> plans
+        for cursors, which will retrieve the first few rows quickly while
+        perhaps taking a long time to fetch all rows.  Larger values
+        put more emphasis on the total estimated time.  At the maximum
+        setting of 1.0, cursors are planned exactly like regular queries,
+        considering only the total estimated time and not how soon the
+        first rows might be delivered.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-from-collapse-limit" xreflabel="from_collapse_limit">
       <term><varname>from_collapse_limit</varname> (<type>integer</type>)</term>
       <indexterm>
index 676af61a700ce4f797563febeca13ad4bdc79639..6c2794571f6f76443fbfedfa0644a599cfa97534 100644 (file)
@@ -42,6 +42,9 @@
 #include "utils/syscache.h"
 
 
+/* GUC parameter */
+double cursor_tuple_fraction = DEFAULT_CURSOR_TUPLE_FRACTION;
+
 /* Hook for plugins to get control in planner() */
 planner_hook_type planner_hook = NULL;
 
@@ -142,11 +145,23 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
        {
                /*
                 * We have no real idea how many tuples the user will ultimately FETCH
-                * from a cursor, but it seems a good bet that he doesn't want 'em
-                * all.  Optimize for 10% retrieval (you gotta better number?  Should
-                * this be a SETtable parameter?)
+                * from a cursor, but it is often the case that he doesn't want 'em
+                * all, or would prefer a fast-start plan anyway so that he can
+                * process some of the tuples sooner.  Use a GUC parameter to decide
+                * what fraction to optimize for.
+                */
+               tuple_fraction = cursor_tuple_fraction;
+
+               /*
+                * We document cursor_tuple_fraction as simply being a fraction,
+                * which means the edge cases 0 and 1 have to be treated specially
+                * here.  We convert 1 to 0 ("all the tuples") and 0 to a very small
+                * fraction.
                 */
-               tuple_fraction = 0.10;
+               if (tuple_fraction >= 1.0)
+                       tuple_fraction = 0.0;
+               else if (tuple_fraction <= 0.0)
+                       tuple_fraction = 1e-10;
        }
        else
        {
index 019de3216cbe1177d8a38f7b5cec04af5e8de36f..4c3e2c874c6571c79589c4da8edd6f06dc9f6dd0 100644 (file)
@@ -1891,6 +1891,16 @@ static struct config_real ConfigureNamesReal[] =
                DEFAULT_CPU_OPERATOR_COST, 0, DBL_MAX, NULL, NULL
        },
 
+       {
+               {"cursor_tuple_fraction", PGC_USERSET, QUERY_TUNING_OTHER,
+                       gettext_noop("Sets the planner's estimate of the fraction of "
+                                                "a cursor's rows that will be retrieved."),
+                       NULL
+               },
+               &cursor_tuple_fraction,
+               DEFAULT_CURSOR_TUPLE_FRACTION, 0.0, 1.0, NULL, NULL
+       },
+
        {
                {"geqo_selection_bias", PGC_USERSET, QUERY_TUNING_GEQO,
                        gettext_noop("GEQO: selective pressure within the population."),
index 9fb567bd62b08d1efa544c005e819001f04d1d84..ce7845308320fe648ae1340dcaff66ef32f5045b 100644 (file)
 
 #default_statistics_target = 10                # range 1-1000
 #constraint_exclusion = off
+#cursor_tuple_fraction = 0.1           # range 0.0-1.0
 #from_collapse_limit = 8
 #join_collapse_limit = 8               # 1 disables collapsing of explicit 
                                        # JOIN clauses
index f7fded820f562bedbbac4e0ca991beb51ca49dd2..716b9501fab6c9d131782f958eac82f0c8ff7c33 100644 (file)
 #include "nodes/plannodes.h"
 #include "nodes/relation.h"
 
+/* GUC parameters */
+#define DEFAULT_CURSOR_TUPLE_FRACTION 0.1
+extern double cursor_tuple_fraction;
+
 /*
  * prototypes for plan/planmain.c
  */