summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-03-20 12:49:17 +0200
committerunknown <monty@mysql.com>2004-03-20 12:49:17 +0200
commit612c949418e869564cf7e04dabb5f3b05c137892 (patch)
tree28dbdf85ca8fb1ef4d8281e2caa779295996e42d /innobase
parent609df311978e24db03d74a6c0d2cdf7003ac57b3 (diff)
parent3e5f1eaecf21e3b2fde0c86838d6740a939b921f (diff)
downloadmariadb-git-612c949418e869564cf7e04dabb5f3b05c137892.tar.gz
Merge mysql.com:/home/my/mysql-4.0 into mysql.com:/home/my/mysql-4.1
innobase/btr/btr0btr.c: Auto merged innobase/btr/btr0cur.c: Auto merged mysys/mf_soundex.c: Auto merged scripts/mysql_install_db.sh: Auto merged
Diffstat (limited to 'innobase')
-rw-r--r--innobase/btr/btr0btr.c63
-rw-r--r--innobase/btr/btr0cur.c24
2 files changed, 50 insertions, 37 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index ee27a171fa5..77bb4231404 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -5,7 +5,7 @@ The B-tree
Created 6/2/1994 Heikki Tuuri
*******************************************************/
-
+
#include "btr0btr.h"
#ifdef UNIV_NONINL
@@ -76,9 +76,6 @@ make them consecutive on disk if possible. From the other file segment
we allocate pages for the non-leaf levels of the tree.
*/
-/* If this many inserts occur sequentially, it affects page split */
-#define BTR_PAGE_SEQ_INSERT_LIMIT 5
-
/******************************************************************
Creates a new index page to the tree (not the root, and also not
used in page reorganization). */
@@ -1089,18 +1086,18 @@ btr_page_get_split_rec_to_left(
page = btr_cur_get_page(cursor);
insert_point = btr_cur_get_rec(cursor);
- if ((page_header_get_ptr(page, PAGE_LAST_INSERT)
- == page_rec_get_next(insert_point))
- && (page_header_get_field(page, PAGE_DIRECTION) == PAGE_LEFT)
- && ((page_header_get_field(page, PAGE_N_DIRECTION)
- >= BTR_PAGE_SEQ_INSERT_LIMIT)
- || (page_header_get_field(page, PAGE_N_DIRECTION) + 1
- >= page_get_n_recs(page)))) {
+ if (page_header_get_ptr(page, PAGE_LAST_INSERT)
+ == page_rec_get_next(insert_point)) {
infimum = page_get_infimum_rec(page);
-
- if ((infimum != insert_point)
- && (page_rec_get_next(infimum) != insert_point)) {
+
+ /* If the convergence is in the middle of a page, include also
+ the record immediately before the new insert to the upper
+ page. Otherwise, we could repeatedly move from page to page
+ lots of records smaller than the convergence point. */
+
+ if (infimum != insert_point
+ && page_rec_get_next(infimum) != insert_point) {
*split_rec = insert_point;
} else {
@@ -1134,29 +1131,29 @@ btr_page_get_split_rec_to_right(
page = btr_cur_get_page(cursor);
insert_point = btr_cur_get_rec(cursor);
- if ((page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point)
- && (page_header_get_field(page, PAGE_DIRECTION) == PAGE_RIGHT)
- && ((page_header_get_field(page, PAGE_N_DIRECTION)
- >= BTR_PAGE_SEQ_INSERT_LIMIT)
- || (page_header_get_field(page, PAGE_N_DIRECTION) + 1
- >= page_get_n_recs(page)))) {
+ /* We use eager heuristics: if the new insert would be right after
+ the previous insert on the same page, we assume that there is a
+ pattern of sequential inserts here. */
+
+ if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) {
supremum = page_get_supremum_rec(page);
- if ((page_rec_get_next(insert_point) != supremum)
- && (page_rec_get_next(page_rec_get_next(insert_point))
- != supremum)
- && (page_rec_get_next(page_rec_get_next(
- page_rec_get_next(insert_point)))
- != supremum)) {
-
- /* If there are >= 3 user records up from the insert
- point, split all but 2 off */
-
- *split_rec = page_rec_get_next(page_rec_get_next(
- page_rec_get_next(insert_point)));
+ if (page_rec_get_next(insert_point) != supremum
+ && page_rec_get_next(page_rec_get_next(insert_point))
+ != supremum) {
+
+ /* If there are >= 2 user records up from the insert
+ point, split all but 1 off. We want to keep one because
+ then sequential inserts can use the adaptive hash
+ index, as they can do the necessary checks of the right
+ search position just by looking at the records on this
+ page. */
+
+ *split_rec = page_rec_get_next(
+ page_rec_get_next(insert_point));
} else {
- /* Else split at inserted record */
+ /* Else split at the new record to insert */
*split_rec = NULL;
}
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index f6a4a6f38f0..fdc8343e190 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -2682,10 +2682,11 @@ btr_estimate_number_of_different_key_vals(
btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
- /* Count the number of different key values minus one
- for each prefix of the key on this index page: we subtract
- one because otherwise our algorithm would give a wrong
- estimate for an index where there is just one key value */
+ /* Count the number of different key values for each prefix of
+ the key on this index page. If the prefix does not determine
+ the index record uniquely in te B-tree, then we subtract one
+ because otherwise our algorithm would give a wrong estimate
+ for an index where there is just one key value. */
page = btr_cur_get_page(&cursor);
@@ -2707,6 +2708,9 @@ btr_estimate_number_of_different_key_vals(
&matched_bytes);
for (j = matched_fields + 1; j <= n_cols; j++) {
+ /* We add one if this index record has
+ a different prefix from the previous */
+
n_diff[j]++;
}
@@ -2716,6 +2720,18 @@ btr_estimate_number_of_different_key_vals(
rec = page_rec_get_next(rec);
}
+ if (n_cols == dict_index_get_n_unique_in_tree(index)) {
+ /* We add one because we know that the first record
+ on the page certainly had a different prefix than the
+ last record on the previous index page in the
+ alphabetical order. Before this fix, if there was
+ just one big record on each clustered index page, the
+ algorithm grossly underestimated the number of rows
+ in the table. */
+
+ n_diff[n_cols]++;
+ }
+
total_external_size +=
btr_rec_get_externally_stored_len(rec);
mtr_commit(&mtr);