]> granicus.if.org Git - postgresql/commitdiff
Add a few comments about ANALYZE's strategy for collecting MCVs.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Apr 2016 21:06:33 +0000 (17:06 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Apr 2016 21:06:33 +0000 (17:06 -0400)
Alex Shulgin complained that the underlying strategy wasn't all that
apparent, particularly not the fact that we intentionally have two
code paths depending on whether we think the column has a limited set
of possible values or not.  Try to make it clearer.

src/backend/commands/analyze.c

index 1283de03348aff0ddb3a08d7051721f73dd7760d..cf8c8164b7e72ba9e913a47726c0b704d02314e1 100644 (file)
@@ -2055,7 +2055,11 @@ compute_distinct_stats(VacAttrStatsP stats,
                        /*
                         * Our track list includes every value in the sample, and every
                         * value appeared more than once.  Assume the column has just
-                        * these values.
+                        * these values.  (This case is meant to address columns with
+                        * small, fixed sets of possible values, such as boolean or enum
+                        * columns.  If there are any values that appear just once in the
+                        * sample, including too-wide values, we should assume that that's
+                        * not what we're dealing with.)
                         */
                        stats->stadistinct = track_cnt;
                }
@@ -2123,6 +2127,16 @@ compute_distinct_stats(VacAttrStatsP stats,
                 * significantly more common than the (estimated) average. We set the
                 * threshold rather arbitrarily at 25% more than average, with at
                 * least 2 instances in the sample.
+                *
+                * Note: the first of these cases is meant to address columns with
+                * small, fixed sets of possible values, such as boolean or enum
+                * columns.  If we can *completely* represent the column population by
+                * an MCV list that will fit into the stats target, then we should do
+                * so and thus provide the planner with complete information.  But if
+                * the MCV list is not complete, it's generally worth being more
+                * selective, and not just filling it all the way up to the stats
+                * target.  So for an incomplete list, we try to take only MCVs that
+                * are significantly more common than average.
                 */
                if (track_cnt < track_max && toowide_cnt == 0 &&
                        stats->stadistinct > 0 &&
@@ -2416,7 +2430,11 @@ compute_scalar_stats(VacAttrStatsP stats,
                {
                        /*
                         * Every value in the sample appeared more than once.  Assume the
-                        * column has just these values.
+                        * column has just these values.  (This case is meant to address
+                        * columns with small, fixed sets of possible values, such as
+                        * boolean or enum columns.  If there are any values that appear
+                        * just once in the sample, including too-wide values, we should
+                        * assume that that's not what we're dealing with.)
                         */
                        stats->stadistinct = ndistinct;
                }
@@ -2485,6 +2503,16 @@ compute_scalar_stats(VacAttrStatsP stats,
                 * emit duplicate histogram bin boundaries.  (We might end up with
                 * duplicate histogram entries anyway, if the distribution is skewed;
                 * but we prefer to treat such values as MCVs if at all possible.)
+                *
+                * Note: the first of these cases is meant to address columns with
+                * small, fixed sets of possible values, such as boolean or enum
+                * columns.  If we can *completely* represent the column population by
+                * an MCV list that will fit into the stats target, then we should do
+                * so and thus provide the planner with complete information.  But if
+                * the MCV list is not complete, it's generally worth being more
+                * selective, and not just filling it all the way up to the stats
+                * target.  So for an incomplete list, we try to take only MCVs that
+                * are significantly more common than average.
                 */
                if (track_cnt == ndistinct && toowide_cnt == 0 &&
                        stats->stadistinct > 0 &&