diff options
author | unknown <marko@hundin.mysql.fi> | 2005-07-04 16:12:08 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2005-07-04 16:12:08 +0300 |
commit | a1da992f4f3da5a5c84a819c80dd5d09db9c66d8 (patch) | |
tree | 29e8f1f9ee7807b8870a57f344abc3178c977c92 | |
parent | 5d82b41e3adccc566b68542bf5be097ed45f5390 (diff) | |
parent | da83833964d877cacdb4e432522d171b3260e06a (diff) | |
download | mariadb-git-a1da992f4f3da5a5c84a819c80dd5d09db9c66d8.tar.gz |
Merge marko@bk-internal.mysql.com:/home/bk/mysql-5.0
into hundin.mysql.fi:/home/marko/mysql-5.0-current
sql/ha_innodb.cc:
Auto merged
-rw-r--r-- | innobase/btr/btr0cur.c | 8 | ||||
-rw-r--r-- | innobase/include/page0cur.h | 6 | ||||
-rw-r--r-- | innobase/page/page0cur.c | 100 | ||||
-rw-r--r-- | innobase/rem/rem0rec.c | 105 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 41 |
5 files changed, 165 insertions, 95 deletions
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 30e85e021bc..d76b139c3c8 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -316,7 +316,9 @@ btr_cur_search_to_nth_level( if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate +#ifdef PAGE_CUR_LE_OR_EXTENDS && mode != PAGE_CUR_LE_OR_EXTENDS +#endif /* PAGE_CUR_LE_OR_EXTENDS */ && srv_use_adaptive_hash_indexes && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, @@ -391,8 +393,10 @@ btr_cur_search_to_nth_level( break; default: ut_ad(mode == PAGE_CUR_L - || mode == PAGE_CUR_LE - || mode == PAGE_CUR_LE_OR_EXTENDS); +#ifdef PAGE_CUR_LE_OR_EXTENDS + || mode == PAGE_CUR_LE_OR_EXTENDS +#endif /* PAGE_CUR_LE_OR_EXTENDS */ + || mode == PAGE_CUR_LE); page_mode = mode; break; } diff --git a/innobase/include/page0cur.h b/innobase/include/page0cur.h index e89e740e775..b03302b0e77 100644 --- a/innobase/include/page0cur.h +++ b/innobase/include/page0cur.h @@ -26,11 +26,13 @@ Created 10/4/1994 Heikki Tuuri #define PAGE_CUR_GE 2 #define PAGE_CUR_L 3 #define PAGE_CUR_LE 4 -#define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in +/*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in "column LIKE 'abc%' ORDER BY column DESC"; we have to find strings which are <= 'abc' or which extend it */ -#define PAGE_CUR_DBG 6 +#ifdef UNIV_SEARCH_DEBUG +# define PAGE_CUR_DBG 6 /* As PAGE_CUR_LE, but skips search shortcut */ +#endif /* UNIV_SEARCH_DEBUG */ #ifdef PAGE_CUR_ADAPT # ifdef UNIV_SEARCH_PERF_STAT diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index df6d898d4ac..562ef545e41 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -47,7 +47,6 @@ page_cur_try_search_shortcut( not yet completely matched */ page_cur_t* cursor) /* out: page cursor */ { - int cmp; rec_t* rec; rec_t* next_rec; ulint low_match; @@ -79,9 +78,8 @@ page_cur_try_search_shortcut( up_match = low_match; up_bytes = low_bytes; - cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, - &low_bytes); - if (cmp == -1) { + if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets, + &low_match, &low_bytes) < 0) { goto exit_func; } @@ -89,9 +87,8 @@ page_cur_try_search_shortcut( offsets = rec_get_offsets(next_rec, index, offsets, dtuple_get_n_fields(tuple), &heap); - cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, - &up_match, &up_bytes); - if (cmp != -1) { + if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, + &up_match, &up_bytes) >= 0) { goto exit_func; } @@ -115,7 +112,7 @@ page_cur_try_search_shortcut( ut_a(*ilow_matched_fields == low_match); ut_a(*ilow_matched_bytes == low_bytes); #endif - if (next_rec != page_get_supremum_rec(page)) { + if (!page_rec_is_supremum(next_rec)) { *iup_matched_fields = up_match; *iup_matched_bytes = up_bytes; @@ -137,6 +134,7 @@ exit_func: #endif +#ifdef PAGE_CUR_LE_OR_EXTENDS /******************************************************************** Checks if the nth field in a record is a character type field which extends the nth field in tuple, i.e., the field is longer or equal in length and has @@ -185,6 +183,7 @@ page_cur_rec_field_extends( return(FALSE); } +#endif /* PAGE_CUR_LE_OR_EXTENDS */ /******************************************************************** Searches the right position for a page cursor. */ @@ -240,9 +239,14 @@ page_cur_search_with_match( ut_ad(dtuple_validate(tuple)); ut_ad(dtuple_check_typed(tuple)); ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE) - || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE) - || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG)); - +#ifdef PAGE_CUR_DBG + || (mode == PAGE_CUR_DBG) +#endif /* PAGE_CUR_DBG */ +#ifdef PAGE_CUR_LE_OR_EXTENDS + || (mode == PAGE_CUR_LE_OR_EXTENDS) +#endif /* PAGE_CUR_LE_OR_EXTENDS */ + || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)); + page_check_dir(page); #ifdef PAGE_CUR_ADAPT @@ -261,16 +265,18 @@ page_cur_search_with_match( return; } } -/*#ifdef UNIV_SEARCH_DEBUG */ +# ifdef PAGE_CUR_DBG if (mode == PAGE_CUR_DBG) { mode = PAGE_CUR_LE; } -/*#endif */ +# endif #endif /* The following flag does not work for non-latin1 char sets because cmp_full_field does not tell how many bytes matched */ +#ifdef PAGE_CUR_LE_OR_EXTENDS ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); +#endif /* PAGE_CUR_LE_OR_EXTENDS */ /* If mode PAGE_CUR_G is specified, we are trying to position the cursor to answer a query of the form "tuple < X", where tuple is @@ -308,33 +314,36 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); - if (cmp == 1) { + if (UNIV_LIKELY(cmp > 0)) { +low_slot_match: low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; - } else if (cmp == -1) { + } else if (UNIV_LIKELY(cmp /* == -1 */)) { +#ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { - low = mid; - low_matched_fields = cur_matched_fields; - low_matched_bytes = cur_matched_bytes; - } else { - up = mid; - up_matched_fields = cur_matched_fields; - up_matched_bytes = cur_matched_bytes; - } - } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE - || mode == PAGE_CUR_LE_OR_EXTENDS) { - low = mid; - low_matched_fields = cur_matched_fields; - low_matched_bytes = cur_matched_bytes; - } else { + goto low_slot_match; + } +#endif /* PAGE_CUR_LE_OR_EXTENDS */ +up_slot_match: up = mid; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; + + } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE +#ifdef PAGE_CUR_LE_OR_EXTENDS + || mode == PAGE_CUR_LE_OR_EXTENDS +#endif /* PAGE_CUR_LE_OR_EXTENDS */ + ) { + + goto low_slot_match; + } else { + + goto up_slot_match; } } @@ -360,32 +369,35 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); - if (cmp == 1) { + if (UNIV_LIKELY(cmp > 0)) { +low_rec_match: low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; - } else if (cmp == -1) { + } else if (UNIV_LIKELY(cmp /* == -1 */)) { +#ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { - low_rec = mid_rec; - low_matched_fields = cur_matched_fields; - low_matched_bytes = cur_matched_bytes; - } else { - up_rec = mid_rec; - up_matched_fields = cur_matched_fields; - up_matched_bytes = cur_matched_bytes; + + goto low_rec_match; } - } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE - || mode == PAGE_CUR_LE_OR_EXTENDS) { - low_rec = mid_rec; - low_matched_fields = cur_matched_fields; - low_matched_bytes = cur_matched_bytes; - } else { +#endif /* PAGE_CUR_LE_OR_EXTENDS */ +up_rec_match: up_rec = mid_rec; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; + } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE +#ifdef PAGE_CUR_LE_OR_EXTENDS + || mode == PAGE_CUR_LE_OR_EXTENDS +#endif /* PAGE_CUR_LE_OR_EXTENDS */ + ) { + + goto low_rec_match; + } else { + + goto up_rec_match; } } diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c index 580a7bfe509..fbc33aea669 100644 --- a/innobase/rem/rem0rec.c +++ b/innobase/rem/rem0rec.c @@ -601,30 +601,38 @@ rec_set_nth_field_extern_bit_new( /* read the lengths of fields 0..n */ for (i = 0; i < n_fields; i++) { - ibool is_null; - ulint len; field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); - is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); - if (is_null) { - /* nullable field => read the null flag */ - is_null = !!(*nulls & null_mask); + if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { + if (UNIV_UNLIKELY(!(byte) null_mask)) { + nulls--; + null_mask = 1; + } + + if (*nulls & null_mask) { + null_mask <<= 1; + /* NULL fields cannot be external. */ + ut_ad(i != ith); + continue; + } + null_mask <<= 1; - if (null_mask == 0x100) - nulls--, null_mask = 1; } - if (is_null || field->fixed_len) { - /* No length (or extern bit) is stored for - fields that are NULL or fixed-length. */ + if (field->fixed_len) { + /* fixed-length fields cannot be external + (Fixed-length fields longer than + DICT_MAX_COL_PREFIX_LEN will be treated as + variable-length ones in dict_index_add_col().) */ ut_ad(i != ith); continue; } - len = *lens--; + lens--; if (dtype_get_len(type) > 255 || dtype_get_mtype(type) == DATA_BLOB) { + ulint len = lens[1]; if (len & 0x80) { /* 1exxxxxx: 2-byte length */ if (i == ith) { - if (!val == !(len & 0x20)) { + if (!val == !(len & 0x40)) { return; /* no change */ } /* toggle the extern bit */ @@ -823,6 +831,7 @@ rec_convert_dtuple_to_rec_new( byte* lens; ulint len; ulint i; + ulint n_node_ptr_field; ulint fixed_len; ulint null_mask = 1; const ulint n_fields = dtuple_get_n_fields(dtuple); @@ -831,16 +840,26 @@ rec_convert_dtuple_to_rec_new( ut_ad(index->table->comp); ut_ad(n_fields > 0); - switch (status) { + + /* Try to ensure that the memset() between the for() loops + completes fast. The address is not exact, but UNIV_PREFETCH + should never generate a memory fault. */ + UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields); + UNIV_PREFETCH_RW(rec); + + switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) { case REC_STATUS_ORDINARY: ut_ad(n_fields <= dict_index_get_n_fields(index)); + n_node_ptr_field = ULINT_UNDEFINED; break; case REC_STATUS_NODE_PTR: ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1); + n_node_ptr_field = n_fields - 1; break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: ut_ad(n_fields == 1); + n_node_ptr_field = ULINT_UNDEFINED; goto init; default: ut_a(0); @@ -852,15 +871,18 @@ rec_convert_dtuple_to_rec_new( rec += (index->n_nullable + 7) / 8; for (i = 0; i < n_fields; i++) { + if (UNIV_UNLIKELY(i == n_node_ptr_field)) { +#ifdef UNIV_DEBUG + field = dtuple_get_nth_field(dtuple, i); + type = dfield_get_type(field); + ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); + ut_ad(dfield_get_len(field) == 4); +#endif /* UNIV_DEBUG */ + goto init; + } field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); - if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { - fixed_len = 4; - ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); - ut_ad(len == 4); - continue; - } fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { @@ -902,27 +924,33 @@ init: type = dfield_get_type(field); len = dfield_get_len(field); - if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { - fixed_len = 4; + if (UNIV_UNLIKELY(i == n_node_ptr_field)) { ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); - goto copy; + memcpy(end, dfield_get_data(field), len); + break; } fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field */ ut_ad(index->n_nullable > 0); + + if (UNIV_UNLIKELY(!(byte) null_mask)) { + nulls--; + null_mask = 1; + } + ut_ad(*nulls < null_mask); + /* set the null flag if necessary */ if (len == UNIV_SQL_NULL) { *nulls |= null_mask; + null_mask <<= 1; + continue; } + null_mask <<= 1; - if (null_mask == 0x100) - nulls--, null_mask = 1; - if (len == UNIV_SQL_NULL) - continue; } /* only nullable fields can be null */ ut_ad(len != UNIV_SQL_NULL); @@ -942,7 +970,7 @@ init: *lens-- = (byte) len; } } - copy: + memcpy(end, dfield_get_data(field), len); end += len; } @@ -1105,7 +1133,6 @@ rec_copy_prefix_to_buf( dtype_t* type; ulint i; ulint prefix_len; - ibool is_null; ulint null_mask; ulint status; @@ -1146,20 +1173,22 @@ rec_copy_prefix_to_buf( for (i = 0; i < n_fields; i++) { field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); - is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); - if (is_null) { + if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field => read the null flag */ - is_null = !!(*nulls & null_mask); - null_mask <<= 1; - if (null_mask == 0x100) { - --nulls; - UNIV_PREFETCH_R(nulls); + if (UNIV_UNLIKELY(!(byte) null_mask)) { + nulls--; null_mask = 1; } + + if (*nulls & null_mask) { + null_mask <<= 1; + continue; + } + + null_mask <<= 1; } - if (is_null) { - } else if (field->fixed_len) { + if (field->fixed_len) { prefix_len += field->fixed_len; } else { ulint len = *lens--; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8b12b43d3d9..8218e4fecc0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2955,21 +2955,44 @@ build_template( templ = prebuilt->mysql_template + n_requested_fields; field = table->field[i]; - ibool index_contains_field= - dict_index_contains_col_or_prefix(index, i); + if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) { + /* Decide which columns we should fetch + and which we can skip. */ + register const ibool index_contains_field = + dict_index_contains_col_or_prefix(index, i); - if (templ_type == ROW_MYSQL_REC_FIELDS && - ((prebuilt->read_just_key && !index_contains_field) || - (!(fetch_all_in_key && index_contains_field) && - !(fetch_primary_key_cols && - dict_table_col_in_clustered_key(index->table, i)) && - thd->query_id != field->query_id))) { + if (!index_contains_field && prebuilt->read_just_key) { + /* If this is a 'key read', we do not need + columns that are not in the key */ + + goto skip_field; + } + + if (index_contains_field && fetch_all_in_key) { + /* This field is needed in the query */ + + goto include_field; + } + + if (thd->query_id == field->query_id) { + /* This field is needed in the query */ + + goto include_field; + } + + if (fetch_primary_key_cols + && dict_table_col_in_clustered_key(index->table, + i)) { + /* This field is needed in the query */ + + goto include_field; + } /* This field is not needed in the query, skip it */ goto skip_field; } - +include_field: n_requested_fields++; templ->col_no = i; |