3176
3176
slot = cursor->path_arr + (root_height - height);
3178
page = page_align(rec);
3180
3178
slot->nth_rec = page_rec_get_n_recs_before(rec);
3181
slot->n_recs = page_get_n_recs(page);
3182
slot->page_no = page_get_page_no(page);
3183
slot->page_level = btr_page_get_level_low(page);
3186
/*******************************************************************//**
3187
Estimate the number of rows between slot1 and slot2 for any level on a
3188
B-tree. This function starts from slot1->page and reads a few pages to
3189
the right, counting their records. If we reach slot2->page quickly then
3190
we know exactly how many records there are between slot1 and slot2 and
3191
we set is_n_rows_exact to TRUE. If we cannot reach slot2->page quickly
3192
then we calculate the average number of records in the pages scanned
3193
so far and assume that all pages that we did not scan up to slot2->page
3194
contain the same number of records, then we multiply that average to
3195
the number of pages between slot1->page and slot2->page (which is
3196
n_rows_on_prev_level). In this case we set is_n_rows_exact to FALSE.
3197
@return number of rows (exact or estimated) */
3200
btr_estimate_n_rows_in_range_on_level(
3201
/*==================================*/
3202
dict_index_t* index, /*!< in: index */
3203
btr_path_t* slot1, /*!< in: left border */
3204
btr_path_t* slot2, /*!< in: right border */
3205
ib_int64_t n_rows_on_prev_level, /*!< in: number of rows
3206
on the previous level for the
3207
same descend paths; used to
3208
determine the numbe of pages
3210
ibool* is_n_rows_exact) /*!< out: TRUE if the returned
3211
value is exact i.e. not an
3221
space = dict_index_get_space(index);
3226
/* Assume by default that we will scan all pages between
3227
slot1->page_no and slot2->page_no */
3228
*is_n_rows_exact = TRUE;
3230
/* add records from slot1->page_no which are to the right of
3231
the record which serves as a left border of the range, if any */
3232
if (slot1->nth_rec < slot1->n_recs) {
3233
n_rows += slot1->n_recs - slot1->nth_rec;
3236
/* add records from slot2->page_no which are to the left of
3237
the record which servers as a right border of the range, if any */
3238
if (slot2->nth_rec > 1) {
3239
n_rows += slot2->nth_rec - 1;
3242
/* count the records in the pages between slot1->page_no and
3243
slot2->page_no (non inclusive), if any */
3245
zip_size = fil_space_get_zip_size(space);
3247
/* Do not read more than this number of pages in order not to hurt
3248
performance with this code which is just an estimation. If we read
3249
this many pages before reaching slot2->page_no then we estimate the
3250
average from the pages scanned so far */
3251
# define N_PAGES_READ_LIMIT 10
3253
page_no = slot1->page_no;
3254
level = slot1->page_level;
3263
/* fetch the page */
3264
block = buf_page_get(space, zip_size, page_no, RW_S_LATCH,
3267
page = buf_block_get_frame(block);
3269
/* It is possible that the tree has been reorganized in the
3270
meantime and this is a different page. If this happens the
3271
calculated estimate will be bogus, which is not fatal as
3272
this is only an estimate. We are sure that a page with
3273
page_no exists because InnoDB never frees pages, only
3275
if (fil_page_get_type(page) != FIL_PAGE_INDEX
3276
|| btr_page_get_index_id(page) != index->id
3277
|| btr_page_get_level_low(page) != level) {
3279
/* 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 */
3179
slot->n_recs = page_get_n_recs(page_align(rec));
3330
3182
/*******************************************************************//**