diff options
author | Igor Babaev <igor@askmonty.org> | 2013-03-02 14:04:11 -0800 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-03-02 14:04:11 -0800 |
commit | fe6c8d42385ef70a9cf928f12a062af1f53ce34b (patch) | |
tree | abe072e832e1ee707e9f660d2456bc68fa4584a6 | |
parent | 6c4f41ff32000580a0a81a98d094a1fb8d1612bf (diff) | |
parent | bd305d6b21fff141ef888f93d98563ed0e7a37e4 (diff) | |
download | mariadb-git-fe6c8d42385ef70a9cf928f12a062af1f53ce34b.tar.gz |
Merge
-rw-r--r-- | mysql-test/r/innodb_ext_key.result | 94 | ||||
-rw-r--r-- | mysql-test/t/innodb_ext_key.test | 76 | ||||
-rw-r--r-- | sql/sql_select.cc | 25 | ||||
-rw-r--r-- | sql/table.cc | 2 |
4 files changed, 181 insertions, 16 deletions
diff --git a/mysql-test/r/innodb_ext_key.result b/mysql-test/r/innodb_ext_key.result index 4e441245a39..0da4feaf26f 100644 --- a/mysql-test/r/innodb_ext_key.result +++ b/mysql-test/r/innodb_ext_key.result @@ -731,6 +731,7 @@ CREATE TABLE t2 (b int) ENGINE=MyISAM; INSERT INTO t1 (a) VALUES (4), (6); INSERT INTO t2 (b) VALUES (0), (8); set @save_optimizer_switch=@@optimizer_switch; +set @save_join_cache_level=@@join_cache_level; SET join_cache_level=3; SET optimizer_switch='join_cache_hashed=on'; SET optimizer_switch='join_cache_bka=on'; @@ -742,6 +743,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.a 2 Using where; Using join buffer (flat, BNLH join) SELECT * FROM t1, t2 WHERE b=a; a b +set join_cache_level=@save_join_cache_level; set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; # @@ -772,5 +774,97 @@ INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar') ON DUPLICATE KEY UPDATE c4 = VALUES(c4); set optimizer_switch=@save_optimizer_switch; DROP TABLE t1; +# +# Bug mdev-4220: using ref instead of eq_ref +# with extended_keys=on +# (performance regression introduced in the patch for mdev-3851) +# +set @save_optimizer_switch=@@optimizer_switch; +create table t1 (a int not null) engine=innodb; +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 ( +pk int primary key, a int not null, b int, unique(a) +)engine=innodb; +insert into t2 +select +A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a +from t1 A, t1 B; +set optimizer_switch='extended_keys=off'; +explain +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 +1 SIMPLE t2 eq_ref a a 4 test.t1.a 1 Using where +flush status; +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +a pk a b +0 0 0 0 +1 1 1 1 +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 10 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 11 +set optimizer_switch='extended_keys=on'; +explain +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 +1 SIMPLE t2 eq_ref a a 4 test.t1.a 1 Using where +flush status; +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +a pk a b +0 0 0 0 +1 1 1 1 +show status like 'handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 10 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 11 +drop table t1,t2; +create table t1(a int) engine=myisam; +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2(a int) engine=myisam; +insert into t2 select A.a + 10*B.a + 100*C.a from t1 A, t1 B, t1 C; +create table t3 ( +pk1 int not null, pk2 int not null, col1 int not null, col2 int not null) +engine=innodb; +insert into t3 select a,a,a,a from t2; +alter table t3 add primary key (pk1, pk2); +alter table t3 add key (col1, col2); +set optimizer_switch='extended_keys=off'; +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t3 ref col1 col1 8 test.t1.a,test.t1.a # Using index +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t3 ref PRIMARY,col1 PRIMARY 4 test.t1.a # Using where +set optimizer_switch='extended_keys=on'; +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t3 ref col1 col1 8 test.t1.a,test.t1.a # Using index +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where +1 SIMPLE t3 ref PRIMARY,col1 col1 12 test.t1.a,test.t1.a,test.t1.a # Using index +drop table t1,t2,t3; +set optimizer_switch=@save_optimizer_switch; set optimizer_switch=@save_ext_key_optimizer_switch; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/innodb_ext_key.test b/mysql-test/t/innodb_ext_key.test index 3e82403ddb5..31c6fca2b95 100644 --- a/mysql-test/t/innodb_ext_key.test +++ b/mysql-test/t/innodb_ext_key.test @@ -414,6 +414,7 @@ INSERT INTO t1 (a) VALUES (4), (6); INSERT INTO t2 (b) VALUES (0), (8); set @save_optimizer_switch=@@optimizer_switch; +set @save_join_cache_level=@@join_cache_level; SET join_cache_level=3; SET optimizer_switch='join_cache_hashed=on'; @@ -424,6 +425,7 @@ EXPLAIN SELECT * FROM t1, t2 WHERE b=a; SELECT * FROM t1, t2 WHERE b=a; +set join_cache_level=@save_join_cache_level; set optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; @@ -466,6 +468,78 @@ set optimizer_switch=@save_optimizer_switch; DROP TABLE t1; +--echo # +--echo # Bug mdev-4220: using ref instead of eq_ref +--echo # with extended_keys=on +--echo # (performance regression introduced in the patch for mdev-3851) +--echo # + +set @save_optimizer_switch=@@optimizer_switch; + +create table t1 (a int not null) engine=innodb; + +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t2 ( + pk int primary key, a int not null, b int, unique(a) +)engine=innodb; + +insert into t2 +select + A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a +from t1 A, t1 B; + +set optimizer_switch='extended_keys=off'; +explain +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +flush status; +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +show status like 'handler_read%'; + +set optimizer_switch='extended_keys=on'; +explain +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +flush status; +select * from t1, t2 where t2.a=t1.a and t2.b < 2; +show status like 'handler_read%'; + +drop table t1,t2; + +# this test case did not demonstrate any regression +# it is added for better testing + +create table t1(a int) engine=myisam; +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); + +create table t2(a int) engine=myisam; +insert into t2 select A.a + 10*B.a + 100*C.a from t1 A, t1 B, t1 C; + +create table t3 ( + pk1 int not null, pk2 int not null, col1 int not null, col2 int not null) +engine=innodb; +insert into t3 select a,a,a,a from t2; +alter table t3 add primary key (pk1, pk2); +alter table t3 add key (col1, col2); + +set optimizer_switch='extended_keys=off'; +--replace_column 9 # +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a; +--replace_column 9 # +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a; + +set optimizer_switch='extended_keys=on'; +--replace_column 9 # +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a; +--replace_column 9 # +explain +select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a; + +drop table t1,t2,t3; + +set optimizer_switch=@save_optimizer_switch; + set optimizer_switch=@save_ext_key_optimizer_switch; SET SESSION STORAGE_ENGINE=DEFAULT; - diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 96ec6881d96..3ac1b03a69d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7987,20 +7987,17 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, ulong key_flags= j->table->actual_key_flags(keyinfo); if (j->type == JT_CONST) j->table->const_table= 1; - else if (((key_flags & (HA_NOSAME | HA_NULL_PART_KEY))!= HA_NOSAME) || - keyparts != j->table->actual_n_key_parts(keyinfo) || - null_ref_key) - { - if (test(key_flags & HA_EXT_NOSAME) && keyparts == keyinfo->ext_key_parts && - !null_ref_key) - j->type= JT_EQ_REF; - else - { - /* Must read with repeat */ - j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; - j->ref.null_ref_key= null_ref_key; - j->ref.null_ref_part= null_ref_part; - } + else if (!((keyparts == keyinfo->key_parts && + ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)) || + (keyparts > keyinfo->key_parts && // true only for extended keys + test(key_flags & HA_EXT_NOSAME) && + keyparts == keyinfo->ext_key_parts)) || + null_ref_key) + { + /* Must read with repeat */ + j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; + j->ref.null_ref_key= null_ref_key; + j->ref.null_ref_part= null_ref_part; } else if (keyuse_uses_no_tables) { diff --git a/sql/table.cc b/sql/table.cc index 4215f667618..c92a096be90 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1003,7 +1003,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } } if (j == first_key_parts) - keyinfo->ext_key_flags= keyinfo->flags | HA_NOSAME | HA_EXT_NOSAME; + keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME; } share->ext_key_parts+= keyinfo->ext_key_parts; } |