Re: Additional improvements to extended statistics
Dean Rasheed <dean.a.rasheed@gmail.com>
From: Dean Rasheed <dean.a.rasheed@gmail.com>
To: Tomas Vondra <tomas.vondra@enterprisedb.com>
Cc: Tomas Vondra <tomas.vondra@2ndquadrant.com>,
Daniel Gustafsson <daniel@yesql.se>, PostgreSQL Hackers <pgsql-hackers@postgresql.org>
Date: 2020-11-29T14:57:42Z
Lists: pgsql-hackers
Attachments
- improve-estimation-of-OR-clauses-20201129.patch (text/x-patch) patch
> On Wed, 18 Nov 2020 at 22:37, Tomas Vondra > <tomas.vondra@enterprisedb.com> wrote: > > > > Seems fine to me, although the "_opt_ext_stats" is rather cryptic. > > AFAICS we use "_internal" for similar functions. > > I have been thinking about this some more. The one part of this that I still wasn't happy with was the way that base frequencies were used to compute the selectivity correction to apply. As noted in [1], using base frequencies in this way isn't really appropriate for clauses combined using "OR". The reason is that an item's base frequency is computed as the product of the per-column selectivities, so that (freq - base_freq) is the right correction to apply for a set of clauses combined with "AND", but it doesn't really work properly for clauses combined with "OR". This is why a number of the estimates in the regression tests end up being significant over-estimates. I speculated in [1] that we might fix that by tracking which columns of the match bitmap actually matched the clauses being estimated, and then only use those base frequencies. Unfortunately that would also mean changing the format of the stats that we store, and so would be a rather invasive change. It occurred to me though, that there is another, much more straightforward way to do it. We can rewrite the "OR" clauses, and turn them into "AND" clauses using the fact that P(A OR B) = P(A) + P(B) - P(A AND B) and then use the multivariate stats to estimate the P(A AND B) part in the usual way. Attached is the resulting patch doing it that way. The main change is in the way that statext_mcv_clauselist_selectivity() works, combined with a new function mcv_clause_selectivity_or() that does the necessary MCV bitmap manipulations. Doing it this way also means that clausesel.c doesn't need to export clauselist_selectivity_or(), and the new set of exported functions seem a bit neater now. A handful of regression test results change, and in all cases except one the new estimates are much better. One estimate is made worse, but in that case we only have 2 sets of partial stats: SELECT * FROM mcv_lists_multi WHERE a = 0 OR b = 0 OR c = 0 OR d = 0 with stats on (a,b) and (c,d) so it's not surprising that combining (a = 0 OR b = 0) with (c = 0 OR d = 0) mis-estimates a bit. I suspect the old MV stats estimate was more down to chance in this case. Regards, Dean [1] https://www.postgresql.org/message-id/CAEZATCX8u9bZzcWEzqA_t7f_OQHu2oxeTUGnFHNEOXnJo35AQg%40mail.gmail.com
Commits
-
Improve estimation of ANDs under ORs using extended statistics.
- 4f5760d4afa9 14.0 landed
-
Improve estimation of OR clauses using multiple extended statistics.
- 88b0898fe35a 14.0 landed
-
Improve estimation of OR clauses using extended statistics.
- 25a9e54d2db3 14.0 landed
-
Prevent functional dependency estimates from exceeding column estimates.
- 87779aa47463 13.0 landed
-
Fix wording of several extended stats comments
- 6f72dbc48bf8 13.0 landed
-
Improve test coverage for multi-column MCV lists
- d8cfa82d51f8 13.0 landed
-
Improve test coverage for functional dependencies
- f9696782c701 13.0 landed