3178
3177
slot = cursor->path_arr + (root_height - height);
3179
page = page_align(rec);
3180
3181
slot->nth_rec = page_rec_get_n_recs_before(rec);
3181
slot->n_recs = page_get_n_recs(page_align(rec));
3182
slot->n_recs = page_get_n_recs(page);
3183
slot->page_no = page_get_page_no(page);
3184
slot->page_level = btr_page_get_level_low(page);
3187
/*******************************************************************//**
3188
Estimate the number of rows between slot1 and slot2 for any level on a
3189
B-tree. This function starts from slot1->page and reads a few pages to
3190
the right, counting their records. If we reach slot2->page quickly then
3191
we know exactly how many records there are between slot1 and slot2 and
3192
we set is_n_rows_exact to TRUE. If we cannot reach slot2->page quickly
3193
then we calculate the average number of records in the pages scanned
3194
so far and assume that all pages that we did not scan up to slot2->page
3195
contain the same number of records, then we multiply that average to
3196
the number of pages between slot1->page and slot2->page (which is
3197
n_rows_on_prev_level). In this case we set is_n_rows_exact to FALSE.
3198
@return number of rows (exact or estimated) */
3201
btr_estimate_n_rows_in_range_on_level(
3202
/*==================================*/
3203
dict_index_t* index, /*!< in: index */
3204
btr_path_t* slot1, /*!< in: left border */
3205
btr_path_t* slot2, /*!< in: right border */
3206
ib_int64_t n_rows_on_prev_level, /*!< in: number of rows
3207
on the previous level for the
3208
same descend paths; used to
3209
determine the numbe of pages
3211
ibool* is_n_rows_exact) /*!< out: TRUE if the returned
3212
value is exact i.e. not an
3222
space = dict_index_get_space(index);
3227
/* Assume by default that we will scan all pages between
3228
slot1->page_no and slot2->page_no */
3229
*is_n_rows_exact = TRUE;
3231
/* add records from slot1->page_no which are to the right of
3232
the record which serves as a left border of the range, if any */
3233
if (slot1->nth_rec < slot1->n_recs) {
3234
n_rows += slot1->n_recs - slot1->nth_rec;
3237
/* add records from slot2->page_no which are to the left of
3238
the record which servers as a right border of the range, if any */
3239
if (slot2->nth_rec > 1) {
3240
n_rows += slot2->nth_rec - 1;
3243
/* count the records in the pages between slot1->page_no and
3244
slot2->page_no (non inclusive), if any */
3246
zip_size = fil_space_get_zip_size(space);
3248
/* Do not read more than this number of pages in order not to hurt
3249
performance with this code which is just an estimation. If we read
3250
this many pages before reaching slot2->page_no then we estimate the
3251
average from the pages scanned so far */
3252
#define N_PAGES_READ_LIMIT 10
3254
page_no = slot1->page_no;
3255
level = slot1->page_level;
3264
/* fetch the page */
3265
block = buf_page_get(space, zip_size, page_no, RW_S_LATCH,
3268
page = buf_block_get_frame(block);
3270
/* It is possible that the tree has been reorganized in the
3271
meantime and this is a different page. If this happens the
3272
calculated estimate will be bogus, which is not fatal as
3273
this is only an estimate. We are sure that a page with
3274
page_no exists because InnoDB never frees pages, only
3276
if (fil_page_get_type(page) != FIL_PAGE_INDEX
3277
|| btr_page_get_index_id(page) != index->id
3278
|| btr_page_get_level_low(page) != level) {
3280
/* The page got reused for something else */
3286
if (page_no != slot1->page_no) {
3287
/* Do not count the records on slot1->page_no,
3288
we already counted them before this loop. */
3289
n_rows += page_get_n_recs(page);
3292
page_no = btr_page_get_next(page, &mtr);
3296
if (n_pages_read == N_PAGES_READ_LIMIT
3297
|| page_no == FIL_NULL) {
3298
/* Either we read too many pages or
3299
we reached the end of the level without passing
3300
through slot2->page_no, the tree must have changed
3305
} while (page_no != slot2->page_no);
3311
*is_n_rows_exact = FALSE;
3313
/* We did interrupt before reaching slot2->page */
3315
if (n_pages_read > 0) {
3316
/* The number of pages on this level is
3317
n_rows_on_prev_level, multiply it by the
3318
average number of recs per page so far */
3319
n_rows = n_rows_on_prev_level
3320
* n_rows / n_pages_read;
3322
/* The tree changed before we could even
3323
start with slot1->page_no */
3184
3330
/*******************************************************************//**