From d426504b9e3e9e92b0c948e912f2b6ffdc89e2d7 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Tue, 11 Dec 2012 10:11:24 +0530 Subject: [PATCH] Bug #14200010 NEWLY CREATED TABLE DOESN'T ALLOW FOR LOOSE INDEX SCANS Problem: Before the ALTER TABLE statement, the array dict_index_t::stat_n_diff_key_vals had proper values calculated and updated. But after the ALTER TABLE statement, all the values of this array is 0. Because of this statistics returned by innodb_rec_per_key() is different before and after the ALTER TABLE statement. Running the ANALYZE TABLE command populates the statistics correctly. Solution: After ALTER TABLE statement, set the flag dict_table_t::stat_initialized correctly so that the table statistics will be recalculated properly when the table is next loaded. But note that we still don't choose the loose index scans. This fix only ensures that an ALTER TABLE does not change the optimizer plan. rb://1639 approved by Marko and Jimmy. --- mysql-test/suite/innodb_plugin/r/innodb-index.result | 2 +- mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 2 +- storage/innodb_plugin/row/row0mysql.c | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-index.result b/mysql-test/suite/innodb_plugin/r/innodb-index.result index bf7c382327b..df853fac078 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-index.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-index.result @@ -963,7 +963,7 @@ Table Op Msg_type Msg_text test.t1 check status OK explain select * from t1 where b like 'adfd%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where +1 SIMPLE t1 range b b 769 NULL 7 Using where create table t2(a int, b varchar(255), primary key(a,b)) engine=innodb; insert into t2 select a,left(b,255) from t1; drop table t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index ebaa52d3b4d..02a3b340057 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -343,7 +343,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary explain select distinct f1, f2 from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary +1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index drop table t1; CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), INDEX (name)); diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 137a164c4cd..9379912a218 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -4083,6 +4083,13 @@ end: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); trx->error_state = DB_SUCCESS; + } else { + if (old_is_tmp && !new_is_tmp) { + /* After ALTER TABLE the table statistics + needs to be rebuilt. It will be rebuilt + when the table is loaded again. */ + table->stat_initialized = FALSE; + } } }