From: Andres Freund Date: Tue, 11 Dec 2018 00:45:59 +0000 (-0800) Subject: zheap: Properly adjust for metapage in estimate_rel_size(). X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=f2515e45f27e26d4693dfaa8c69f3bda62d8300d;p=users%2Fandresfreund%2Fpostgres.git zheap: Properly adjust for metapage in estimate_rel_size(). Previously *pages wasn't adapted for the metapage, leading to superflous plan changes. Also, avoid multiple checks. Author: Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 6b33814f39..846866ce37 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -969,6 +969,23 @@ estimate_rel_size(Relation rel, int32 *attr_widths, /* it has storage, ok to call the smgr */ curpages = RelationGetNumberOfBlocks(rel); + /* coerce values in pg_class to more desirable types */ + relpages = (BlockNumber) rel->rd_rel->relpages; + reltuples = (double) rel->rd_rel->reltuples; + relallvisible = (BlockNumber) rel->rd_rel->relallvisible; + + /* + * If it's a zheap relation, then subtract one page to account for + * the metapage. + */ + if (RelationStorageIsZHeap(rel)) + { + if (curpages > 0) + curpages--; + if (relpages > 0) + relpages--; + } + /* * HACK: if the relation has never yet been vacuumed, use a * minimum size estimate of 10 pages. The idea here is to avoid @@ -1000,9 +1017,7 @@ estimate_rel_size(Relation rel, int32 *attr_widths, * minimum to indexes. */ if (curpages < 10 && - (rel->rd_rel->relpages == 0 || - (RelationStorageIsZHeap(rel) && - rel->rd_rel->relpages == ZHEAP_METAPAGE + 1)) && + relpages == 0 && !rel->rd_rel->relhassubclass && rel->rd_rel->relkind != RELKIND_INDEX) curpages = 10; @@ -1010,27 +1025,13 @@ estimate_rel_size(Relation rel, int32 *attr_widths, /* report estimated # pages */ *pages = curpages; /* quick exit if rel is clearly empty */ - if (curpages == 0 || (RelationStorageIsZHeap(rel) && - curpages == ZHEAP_METAPAGE + 1)) + if (curpages == 0) { *tuples = 0; *allvisfrac = 0; break; } - /* coerce values in pg_class to more desirable types */ - relpages = (BlockNumber) rel->rd_rel->relpages; - reltuples = (double) rel->rd_rel->reltuples; - relallvisible = (BlockNumber) rel->rd_rel->relallvisible; - /* - * If it's a zheap relation, then subtract the pages - * to account for the metapage. - */ - if (relpages > 0 && RelationStorageIsZHeap(rel)) - { - curpages--; - relpages--; - } /* * If it's an index, discount the metapage while estimating the * number of tuples. This is a kluge because it assumes more than