On Sat, 12 Apr 2025 at 20:29, Corey Huinker <corey.huin...@gmail.com> wrote:
>>
>> at the *actual size* of the relation and takes that into account when
>> scaling the statistics (see table_block_relation_estimate_size() in
>> tableam.c). If the table sizes don't match between the two servers
>> then there's no guarantees the planner will produce the same plan.
>
> Sorry that I didn't see this thread until now. I would like to note that 
> table_block_relation_estimate_size() determines the actual size of the 
> relation by asking pg_class, and the relevant values there are set by 
> pg_restore_relation_stats().

Sorry, this isn't correct. I suspect you're probably misreading the
code. On a fleeting glance, you might have seen the "relpages =
(BlockNumber) rel->rd_rel->relpages;" line and come to this
conclusion. A more careful study will reveal the truth. Check for
"curpages = RelationGetNumberOfBlocks(rel);" and an unconditional
"*pages = curpages;".

You might be getting confused because the code does look at the
pg_class fields, but that's only to estimate the tuple density. When
pg_class has those estimates, they're used to calculate the estimated
density by doing reltuples / relpages, but that average rows per page
is then applied to the *actual* number of pages in the relation. This
method allows the stats to be scaled as the table grows and that take
effect without waiting for vacuum or analyze to update the pg_class
fields. The planner checks the current size of the table every time it
plans a query. That's very well understood and documented. See [1].

David

[1] 
https://www.postgresql.org/docs/current/row-estimation-examples.html#ROW-ESTIMATION-EXAMPLES


Reply via email to