Re: Row estimates for empty tables

From: David Rowley <dgrowleyml(at)gmail(dot)com>
To: Christophe Pettus <xof(at)thebuild(dot)com>
Cc: postgre <pgsql-general(at)lists(dot)postgresql(dot)org>
Subject: Re: Row estimates for empty tables
Date: 2020-07-24 04:56:49
Message-ID: CAApHDvrC8crSPSxQnEJ8W+mVDZAiaQyT0PryHbmW8RnoSbQmbg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers

On Fri, 24 Jul 2020 at 16:01, Christophe Pettus <xof(at)thebuild(dot)com> wrote:
> I realize I've never quite known this; where does the planner get the row estimates for an empty table? Example:

We just assume there are 10 pages if the relation has not yet been
vacuumed or analyzed. The row estimates you see are the number of
times 1 tuple is likely to fit onto a single page multiplied by the
assumed 10 pages. If you had made your table wider then the planner
would have assumed fewer rows

There's a comment that justifies the 10 pages, which, as of master is
in table_block_relation_estimate_size(). It'll be somewhere else in
pg12.

* HACK: if the relation has never yet been vacuumed, use a minimum size
* estimate of 10 pages. The idea here is to avoid assuming a
* newly-created table is really small, even if it currently is, because
* that may not be true once some data gets loaded into it. Once a vacuum
* or analyze cycle has been done on it, it's more reasonable to believe
* the size is somewhat stable.
*
* (Note that this is only an issue if the plan gets cached and used again
* after the table has been filled. What we're trying to avoid is using a
* nestloop-type plan on a table that has grown substantially since the
* plan was made. Normally, autovacuum/autoanalyze will occur once enough
* inserts have happened and cause cached-plan invalidation; but that
* doesn't happen instantaneously, and it won't happen at all for cases
* such as temporary tables.)
*
* We approximate "never vacuumed" by "has relpages = 0", which means this
* will also fire on genuinely empty relations. Not great, but
* fortunately that's a seldom-seen case in the real world, and it
* shouldn't degrade the quality of the plan too much anyway to err in
* this direction.
*
* If the table has inheritance children, we don't apply this heuristic.
* Totally empty parent tables are quite common, so we should be willing
* to believe that they are empty.

The code which decides if the table has been vacuumed here assumes it
has not if pg_class.relpages == 0. So even if you were to manually
vacuum the table the code here would think it's not yet been vacuumed.

David

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Tom Lane 2020-07-24 13:48:36 Re: Row estimates for empty tables
Previous Message Christophe Pettus 2020-07-24 04:01:25 Row estimates for empty tables

Browse pgsql-hackers by date

  From Date Subject
Next Message Amul Sul 2020-07-24 05:13:54 Re: [Patch] ALTER SYSTEM READ ONLY
Previous Message Christophe Pettus 2020-07-24 04:01:25 Row estimates for empty tables