summaryrefslogtreecommitdiff
path: root/innobase/btr/btr0cur.c
diff options
context:
space:
mode:
authorunknown <heikki@donna.mysql.fi>2001-12-11 23:42:31 +0200
committerunknown <heikki@donna.mysql.fi>2001-12-11 23:42:31 +0200
commit6a30dc343775c65d4e6b440c65573227055204a4 (patch)
tree9bd5e7c0b8309ce0aa958ea02118585e4709add0 /innobase/btr/btr0cur.c
parentd469dba9e291f07867b3965fe8799651a202bdaa (diff)
downloadmariadb-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.c67
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