diff options
author | unknown <heikki@donna.mysql.fi> | 2001-12-11 23:42:31 +0200 |
---|---|---|
committer | unknown <heikki@donna.mysql.fi> | 2001-12-11 23:42:31 +0200 |
commit | 6a30dc343775c65d4e6b440c65573227055204a4 (patch) | |
tree | 9bd5e7c0b8309ce0aa958ea02118585e4709add0 /innobase/btr/btr0cur.c | |
parent | d469dba9e291f07867b3965fe8799651a202bdaa (diff) | |
download | mariadb-git-6a30dc343775c65d4e6b440c65573227055204a4.tar.gz |
btr0cur.c:
Improve table cardinality estimate if there are big BLOBs
innobase/btr/btr0cur.c:
Improve table cardinality estimate if there are big BLOBs
Diffstat (limited to 'innobase/btr/btr0cur.c')
-rw-r--r-- | innobase/btr/btr0cur.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 70de09f0fd9..da51be11176 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -85,6 +85,15 @@ btr_rec_free_updated_extern_fields( inherited fields */ mtr_t* mtr); /* in: mini-transaction handle which contains an X-latch to record page and to the tree */ +/*************************************************************** +Gets the externally stored size of a record, in units of a database page. */ +static +ulint +btr_rec_get_externally_stored_len( +/*==============================*/ + /* out: externally stored part, in units of a + database page */ + rec_t* rec); /* in: record */ /*==================== B-TREE SEARCH =========================*/ @@ -2540,6 +2549,7 @@ btr_estimate_number_of_different_key_vals( ulint matched_bytes; ulint* n_diff; ulint not_empty_flag = 0; + ulint total_external_size = 0; ulint i; ulint j; mtr_t mtr; @@ -2586,10 +2596,15 @@ btr_estimate_number_of_different_key_vals( for (j = matched_fields + 1; j <= n_cols; j++) { n_diff[j]++; } - + + total_external_size += + btr_rec_get_externally_stored_len(rec); + rec = page_rec_get_next(rec); } + total_external_size += + btr_rec_get_externally_stored_len(rec); mtr_commit(&mtr); } @@ -2597,12 +2612,18 @@ btr_estimate_number_of_different_key_vals( BTR_KEY_VAL_ESTIMATE_N_PAGES leaf pages, we can estimate how many there will be in index->stat_n_leaf_pages */ + /* We must take into account that our sample actually represents + also the pages used for external storage of fields (those pages are + included in index->stat_n_leaf_pages) */ + for (j = 0; j <= n_cols; j++) { index->stat_n_diff_key_vals[j] = (n_diff[j] * index->stat_n_leaf_pages + BTR_KEY_VAL_ESTIMATE_N_PAGES - 1 + + total_external_size + not_empty_flag) - / BTR_KEY_VAL_ESTIMATE_N_PAGES; + / (BTR_KEY_VAL_ESTIMATE_N_PAGES + + total_external_size); } mem_free(n_diff); @@ -2610,6 +2631,48 @@ btr_estimate_number_of_different_key_vals( /*================== EXTERNAL STORAGE OF BIG FIELDS ===================*/ +/*************************************************************** +Gets the externally stored size of a record, in units of a database page. */ +static +ulint +btr_rec_get_externally_stored_len( +/*==============================*/ + /* out: externally stored part, in units of a + database page */ + rec_t* rec) /* in: record */ +{ + ulint n_fields; + byte* data; + ulint local_len; + ulint extern_len; + ulint total_extern_len = 0; + ulint i; + + if (rec_get_data_size(rec) <= REC_1BYTE_OFFS_LIMIT) { + + return(0); + } + + n_fields = rec_get_n_fields(rec); + + for (i = 0; i < n_fields; i++) { + if (rec_get_nth_field_extern_bit(rec, i)) { + + data = rec_get_nth_field(rec, i, &local_len); + + local_len -= BTR_EXTERN_FIELD_REF_SIZE; + + extern_len = mach_read_from_4(data + local_len + + BTR_EXTERN_LEN + 4); + + total_extern_len += ut_calc_align(extern_len, + UNIV_PAGE_SIZE); + } + } + + return(total_extern_len / UNIV_PAGE_SIZE); +} + /*********************************************************************** Sets the ownership bit of an externally stored field in a record. */ static |