]> granicus.if.org Git - postgresql/commitdiff
Fix thinko in estimate_num_groups
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 27 Mar 2017 15:52:50 +0000 (12:52 -0300)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Mon, 27 Mar 2017 16:14:23 +0000 (13:14 -0300)
The code for the reworked n-distinct estimation on commit 7b504eb282 was
written differently in a previous version of the patch, prior to commit;
on rewriting it, we missed updating an initializer.  This caused the
code to (mistakenly) apply a fudge factor even in the case where a
single value is applied, leading to incorrect results.

This means that the 'relvarcount' variable name is now wrong.  Add a
comment to try and make the situation clearer, and remove an incorrect
comment I added.

Problem noticed, and code patch, by Tomas Vondra.  Additional commentary
by Álvaro.

src/backend/utils/adt/selfuncs.c

index cc24c8aeb56ef087bacb271f6fc0cc7257ad2d76..5c382a2013e2b09905deef9cfaa70bf1ad765e3e 100644 (file)
@@ -3404,7 +3404,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
                RelOptInfo *rel = varinfo1->rel;
                double          reldistinct = 1;
                double          relmaxndistinct = reldistinct;
-               int                     relvarcount = 1;
+               int                     relvarcount = 0;
                List       *newvarinfos = NIL;
                List       *relvarinfos = NIL;
 
@@ -3436,6 +3436,10 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
                 * we multiply them together.  Any remaining relvarinfos after
                 * no more multivariate matches are found are assumed independent too,
                 * so their individual ndistinct estimates are multiplied also.
+                *
+                * While iterating, count how many separate numdistinct values we
+                * apply.  We apply a fudge factor below, but only if we multiplied
+                * more than one such values.
                 */
                while (relvarinfos)
                {
@@ -3447,7 +3451,7 @@ estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows,
                                reldistinct *= mvndistinct;
                                if (relmaxndistinct < mvndistinct)
                                        relmaxndistinct = mvndistinct;
-                               relvarcount++;  /* inaccurate, but doesn't matter */
+                               relvarcount++;
                        }
                        else
                        {