aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2019-11-21 10:23:38 +0900
committerMichael Paquier <michael@paquier.xyz>2019-11-21 10:23:38 +0900
commitc644407f757c26c9037e4dfc67f57b841489afd4 (patch)
tree80f64837e502a47b5874cefe5663c594c3e40e05
parent2c9772f5f5b4172d7332c7fbf742d773bdf44e1c (diff)
downloadpostgresql-c644407f757c26c9037e4dfc67f57b841489afd4.tar.gz
postgresql-c644407f757c26c9037e4dfc67f57b841489afd4.zip
Provide statistics for hypothetical BRIN indexes
Trying to use hypothetical indexes with BRIN currently fails when trying to access a relation that does not exist when looking for the statistics. With the current API, it is not possible to easily pass a value for pages_per_range down to the hypothetical index, so this makes use of the default value of BRIN_DEFAULT_PAGES_PER_RANGE, which should be fine enough in most cases. Being able to refine or enforce the hypothetical costs in more optimistic ways would require more refactoring by filling in the statistics when building IndexOptInfo in plancat.c. This would involve ABI breakages around the costing routines, something not fit for stable branches. This is broken since 7e534ad, so backpatch down to v10. Author: Julien Rouhaud, Heikki Linnakangas Reviewed-by: Álvaro Herrera, Tom Lane, Michael Paquier Discussion: https://postgr.es/m/CAOBaU_ZH0LKEA8VFCocr6Lpte1ab0b6FpvgS0y4way+RPSXfYg@mail.gmail.com Backpatch-through: 10
-rw-r--r--src/backend/utils/adt/selfuncs.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 8f9d0211f85..f84ca5c727a 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -102,6 +102,7 @@
#include <math.h>
#include "access/brin.h"
+#include "access/brin_page.h"
#include "access/gin.h"
#include "access/table.h"
#include "access/tableam.h"
@@ -6884,12 +6885,34 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
&spc_seq_page_cost);
/*
- * Obtain some data from the index itself. A lock should have already
- * been obtained on the index in plancat.c.
+ * Obtain some data from the index itself, if possible. Otherwise invent
+ * some plausible internal statistics based on the relation page count.
*/
- indexRel = index_open(index->indexoid, NoLock);
- brinGetStats(indexRel, &statsData);
- index_close(indexRel, NoLock);
+ if (!index->hypothetical)
+ {
+ /*
+ * A lock should have already been obtained on the index in plancat.c.
+ */
+ indexRel = index_open(index->indexoid, NoLock);
+ brinGetStats(indexRel, &statsData);
+ index_close(indexRel, NoLock);
+
+ /* work out the actual number of ranges in the index */
+ indexRanges = Max(ceil((double) baserel->pages /
+ statsData.pagesPerRange), 1.0);
+ }
+ else
+ {
+ /*
+ * Assume default number of pages per range, and estimate the number
+ * of ranges based on that.
+ */
+ indexRanges = Max(ceil((double) baserel->pages /
+ BRIN_DEFAULT_PAGES_PER_RANGE), 1.0);
+
+ statsData.pagesPerRange = BRIN_DEFAULT_PAGES_PER_RANGE;
+ statsData.revmapNumPages = (indexRanges / REVMAP_PAGE_MAXITEMS) + 1;
+ }
/*
* Compute index correlation
@@ -6989,10 +7012,6 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
baserel->relid,
JOIN_INNER, NULL);
- /* work out the actual number of ranges in the index */
- indexRanges = Max(ceil((double) baserel->pages / statsData.pagesPerRange),
- 1.0);
-
/*
* Now calculate the minimum possible ranges we could match with if all of
* the rows were in the perfect order in the table's heap.