diff options
author | unknown <heikki@hundin.mysql.fi> | 2004-03-17 19:37:48 +0200 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2004-03-17 19:37:48 +0200 |
commit | 68273f0f84597c92a8b727f415564df87bcdb0a5 (patch) | |
tree | c5d75fedad7590ad42c86f32a245754a2a6e548e | |
parent | 8bdbfee96b876e48387cdc14d6b44a18d82a1043 (diff) | |
download | mariadb-git-68273f0f84597c92a8b727f415564df87bcdb0a5.tar.gz |
Many files:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
innobase/dict/dict0dict.c:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
innobase/include/dict0dict.h:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
innobase/include/row0mysql.h:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
sql/ha_innodb.cc:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
sql/sql_select.cc:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
include/my_base.h:
Fix Bug #1942: do not retrieve all columns in a table if we only need the 'ref' of the row (usually, the PRIMARY KEY) to calculate an ORDER BY
-rw-r--r-- | include/my_base.h | 8 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 40 | ||||
-rw-r--r-- | innobase/include/dict0dict.h | 11 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 21 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 42 | ||||
-rw-r--r-- | sql/sql_select.cc | 2 |
6 files changed, 98 insertions, 26 deletions
diff --git a/include/my_base.h b/include/my_base.h index e2b6d010d69..cfdab6a49ba 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -131,10 +131,14 @@ enum ha_extra_function { HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/ HA_EXTRA_NO_IGNORE_DUP_KEY, /* - Instructs InnoDB to retrieve all columns, not just those where - field->query_id is the same as the current query id + Instructs InnoDB to retrieve all columns (except in key read), not just + those where field->query_id is the same as the current query id */ HA_EXTRA_RETRIEVE_ALL_COLS, + /* + Instructs InnoDB to retrieve at least all the primary key columns + */ + HA_EXTRA_RETRIEVE_PRIMARY_KEY, HA_EXTRA_PREPARE_FOR_DELETE, HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */ HA_EXTRA_PRELOAD_BUFFER_SIZE /* Set buffer size for preloading */ diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 13ed5bd9af1..3085142e22e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -631,7 +631,7 @@ dict_table_get_on_id( } /************************************************************************ -Looks for column n postion in the clustered index. */ +Looks for column n position in the clustered index. */ ulint dict_table_get_nth_col_pos( @@ -645,6 +645,44 @@ dict_table_get_nth_col_pos( n)); } +/************************************************************************ +Checks if a column is in the ordering columns of the clustered index of a +table. Column prefixes are treated like whole columns. */ + +ibool +dict_table_col_in_clustered_key( +/*============================*/ + /* out: TRUE if the column, or its prefix, is + in the clustered key */ + dict_table_t* table, /* in: table */ + ulint n) /* in: column number */ +{ + dict_index_t* index; + dict_field_t* field; + dict_col_t* col; + ulint pos; + ulint n_fields; + + ut_ad(table); + + col = dict_table_get_nth_col(table, n); + + index = dict_table_get_first_index(table); + + n_fields = dict_index_get_n_unique(index); + + for (pos = 0; pos < n_fields; pos++) { + field = dict_index_get_nth_field(index, pos); + + if (col == field->col) { + + return(TRUE); + } + } + + return(FALSE); +} + /************************************************************************** Inits the data dictionary module. */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 534c9e380b8..688685cff8b 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -493,6 +493,17 @@ dict_table_get_sys_col_no( /* out: column number */ dict_table_t* table, /* in: table */ ulint sys); /* in: DATA_ROW_ID, ... */ +/************************************************************************ +Checks if a column is in the ordering columns of the clustered index of a +table. Column prefixes are treated like whole columns. */ + +ibool +dict_table_col_in_clustered_key( +/*============================*/ + /* out: TRUE if the column, or its prefix, is + in the clustered key */ + dict_table_t* table, /* in: table */ + ulint n); /* in: column number */ /*********************************************************************** Copies types of columns contained in table to tuple. */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index fade3709631..32a0c8b5d75 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -510,13 +510,15 @@ struct row_prebuilt_struct { byte* ins_upd_rec_buff;/* buffer for storing data converted to the Innobase format from the MySQL format */ - ibool hint_no_need_to_fetch_extra_cols; - /* normally this is TRUE, but - MySQL will set this to FALSE - if we might be required to fetch also - other columns than mentioned in the - query: the clustered index column(s), - or an auto-increment column*/ + ulint hint_need_to_fetch_extra_cols; + /* normally this is set to 0; if this + is set to ROW_RETRIEVE_PRIMARY_KEY, + then we should at least retrieve all + columns in the primary key; if this + is set to ROW_RETRIEVE_ALL_COLS, then + we must retrieve all columns in the + key (if read_just_key == 1), or all + columns in the table */ upd_node_t* upd_node; /* Innobase SQL update node used to perform updates and deletes */ que_fork_t* ins_graph; /* Innobase SQL query graph used @@ -572,6 +574,11 @@ struct row_prebuilt_struct { #define ROW_MYSQL_DUMMY_TEMPLATE 3 /* dummy template used in row_scan_and_check_index */ +/* Values for hint_need_to_fetch_extra_cols */ +#define ROW_RETRIEVE_PRIMARY_KEY 1 +#define ROW_RETRIEVE_ALL_COLS 2 + + #ifndef UNIV_NONINL #include "row0mysql.ic" #endif diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 078238fe78f..8e190904e05 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -702,7 +702,7 @@ ha_innobase::init_table_handle_for_HANDLER(void) /* Always fetch all columns in the index record */ - prebuilt->hint_no_need_to_fetch_extra_cols = FALSE; + prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS; /* We want always to fetch all columns in the whole row? Or do we???? */ @@ -1951,6 +1951,7 @@ build_template( ulint n_fields; ulint n_requested_fields = 0; ibool fetch_all_in_key = FALSE; + ibool fetch_primary_key_cols = FALSE; ulint i; if (prebuilt->select_lock_type == LOCK_X) { @@ -1961,8 +1962,9 @@ build_template( templ_type = ROW_MYSQL_WHOLE_ROW; } - if (templ_type == ROW_MYSQL_REC_FIELDS - && !prebuilt->hint_no_need_to_fetch_extra_cols) { + if (templ_type == ROW_MYSQL_REC_FIELDS) { + if (prebuilt->hint_need_to_fetch_extra_cols + == ROW_RETRIEVE_ALL_COLS) { /* We know we must at least fetch all columns in the key, or all columns in the table */ @@ -1977,15 +1979,14 @@ build_template( fetch_all_in_key = TRUE; } else { - /* We are building a temporary table: fetch all - columns; the reason is that MySQL may use the - clustered index key to store rows, but the mechanism - we use below to detect required columns does not - reveal that. Actually, it might be enough to - fetch only all in the key also in this case! */ - templ_type = ROW_MYSQL_WHOLE_ROW; } + } else if (prebuilt->hint_need_to_fetch_extra_cols + == ROW_RETRIEVE_PRIMARY_KEY) { + /* We must at least fetch all primary key cols */ + + fetch_primary_key_cols = TRUE; + } } clust_index = dict_table_get_first_index_noninline(prebuilt->table); @@ -2004,7 +2005,7 @@ build_template( the clustered index */ } - n_fields = (ulint)table->fields; + n_fields = (ulint)table->fields; /* number of columns */ if (!prebuilt->mysql_template) { prebuilt->mysql_template = (mysql_row_templ_t*) @@ -2017,6 +2018,8 @@ build_template( prebuilt->templ_contains_blob = FALSE; + /* Note that in InnoDB, i is the column number. MySQL calls columns + 'fields'. */ for (i = 0; i < n_fields; i++) { templ = prebuilt->mysql_template + n_requested_fields; field = table->field[i]; @@ -2029,6 +2032,8 @@ build_template( if (templ_type == ROW_MYSQL_REC_FIELDS && !(fetch_all_in_key && dict_index_contains_col_or_prefix(index, i)) + && !(fetch_primary_key_cols + && dict_table_col_in_clustered_key(index->table, i)) && thd->query_id != field->query_id) { /* This field is not needed in the query, skip it */ @@ -4514,7 +4519,14 @@ ha_innobase::extra( prebuilt->read_just_key = 0; break; case HA_EXTRA_RETRIEVE_ALL_COLS: - prebuilt->hint_no_need_to_fetch_extra_cols = FALSE; + prebuilt->hint_need_to_fetch_extra_cols + = ROW_RETRIEVE_ALL_COLS; + break; + case HA_EXTRA_RETRIEVE_PRIMARY_KEY: + if (prebuilt->hint_need_to_fetch_extra_cols == 0) { + prebuilt->hint_need_to_fetch_extra_cols + = ROW_RETRIEVE_PRIMARY_KEY; + } break; case HA_EXTRA_KEYREAD: prebuilt->read_just_key = 1; @@ -4575,7 +4587,7 @@ ha_innobase::start_stmt( auto_inc_counter_for_this_stat = 0; prebuilt->sql_stat_start = TRUE; - prebuilt->hint_no_need_to_fetch_extra_cols = TRUE; + prebuilt->hint_need_to_fetch_extra_cols = 0; prebuilt->read_just_key = 0; if (!prebuilt->mysql_has_locked) { @@ -4652,7 +4664,7 @@ ha_innobase::external_lock( trx = prebuilt->trx; prebuilt->sql_stat_start = TRUE; - prebuilt->hint_no_need_to_fetch_extra_cols = TRUE; + prebuilt->hint_need_to_fetch_extra_cols = 0; prebuilt->read_just_key = 0; @@ -4996,7 +5008,7 @@ ha_innobase::innobase_read_and_init_auto_inc( /* Play safe and also give in another way the hint to fetch all columns in the key: */ - prebuilt->hint_no_need_to_fetch_extra_cols = FALSE; + prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS; prebuilt->trx->mysql_n_tables_locked += 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 13efad05eb9..09017c7b9ce 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -845,7 +845,7 @@ JOIN::optimize() for (uint i_h = const_tables; i_h < tables; i_h++) { TABLE* table_h = join_tab[i_h].table; - table_h->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); + table_h->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); } } #endif |