@@ -5171,6 +5171,8 @@ compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, Path *bitmapqual,
5171
5171
double T ;
5172
5172
double pages_fetched ;
5173
5173
double tuples_fetched ;
5174
+ double heap_pages ;
5175
+ long maxentries ;
5174
5176
5175
5177
/*
5176
5178
* Fetch total cost of obtaining the bitmap, as well as its total
@@ -5185,6 +5187,24 @@ compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, Path *bitmapqual,
5185
5187
5186
5188
T = (baserel -> pages > 1 ) ? (double ) baserel -> pages : 1.0 ;
5187
5189
5190
+ /*
5191
+ * For a single scan, the number of heap pages that need to be fetched is
5192
+ * the same as the Mackert and Lohman formula for the case T <= b (ie, no
5193
+ * re-reads needed).
5194
+ */
5195
+ pages_fetched = (2.0 * T * tuples_fetched ) / (2.0 * T + tuples_fetched );
5196
+
5197
+ /*
5198
+ * Calculate the number of pages fetched from the heap. Then based on
5199
+ * current work_mem estimate get the estimated maxentries in the bitmap.
5200
+ * (Note that we always do this calculation based on the number of pages
5201
+ * that would be fetched in a single iteration, even if loop_count > 1.
5202
+ * That's correct, because only that number of entries will be stored in
5203
+ * the bitmap at one time.)
5204
+ */
5205
+ heap_pages = Min (pages_fetched , baserel -> pages );
5206
+ maxentries = tbm_calculate_entries (work_mem * 1024L );
5207
+
5188
5208
if (loop_count > 1 )
5189
5209
{
5190
5210
/*
@@ -5199,22 +5219,41 @@ compute_bitmap_pages(PlannerInfo *root, RelOptInfo *baserel, Path *bitmapqual,
5199
5219
root );
5200
5220
pages_fetched /= loop_count ;
5201
5221
}
5202
- else
5203
- {
5204
- /*
5205
- * For a single scan, the number of heap pages that need to be fetched
5206
- * is the same as the Mackert and Lohman formula for the case T <= b
5207
- * (ie, no re-reads needed).
5208
- */
5209
- pages_fetched =
5210
- (2.0 * T * tuples_fetched ) / (2.0 * T + tuples_fetched );
5211
- }
5212
5222
5213
5223
if (pages_fetched >= T )
5214
5224
pages_fetched = T ;
5215
5225
else
5216
5226
pages_fetched = ceil (pages_fetched );
5217
5227
5228
+ if (maxentries < heap_pages )
5229
+ {
5230
+ double exact_pages ;
5231
+ double lossy_pages ;
5232
+
5233
+ /*
5234
+ * Crude approximation of the number of lossy pages. Because of the
5235
+ * way tbm_lossify() is coded, the number of lossy pages increases
5236
+ * very sharply as soon as we run short of memory; this formula has
5237
+ * that property and seems to perform adequately in testing, but it's
5238
+ * possible we could do better somehow.
5239
+ */
5240
+ lossy_pages = Max (0 , heap_pages - maxentries / 2 );
5241
+ exact_pages = heap_pages - lossy_pages ;
5242
+
5243
+ /*
5244
+ * If there are lossy pages then recompute the number of tuples
5245
+ * processed by the bitmap heap node. We assume here that the chance
5246
+ * of a given tuple coming from an exact page is the same as the
5247
+ * chance that a given page is exact. This might not be true, but
5248
+ * it's not clear how we can do any better.
5249
+ */
5250
+ if (lossy_pages > 0 )
5251
+ tuples_fetched =
5252
+ clamp_row_est (indexSelectivity *
5253
+ (exact_pages / heap_pages ) * baserel -> tuples +
5254
+ (lossy_pages / heap_pages ) * baserel -> tuples );
5255
+ }
5256
+
5218
5257
if (cost )
5219
5258
* cost = indexTotalCost ;
5220
5259
if (tuple )
0 commit comments