diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-04 10:07:29 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-06-04 10:07:29 +0300 |
commit | 3c97097f11bf111b7b25378e0c05011849e57541 (patch) | |
tree | 6651c2ba0985109fa545932588dd4be35dd6866a | |
parent | 8426c7411bcd1c3efec6a65db98266b0cad5f62a (diff) | |
parent | bab4348c6c1253f8d23f688f7ac083a4e902b701 (diff) | |
download | mariadb-git-3c97097f11bf111b7b25378e0c05011849e57541.tar.gz |
Merge 10.4 into 10.5
-rw-r--r-- | mysql-test/main/derived_cond_pushdown.result | 2 | ||||
-rw-r--r-- | mysql-test/main/derived_split_innodb.result | 65 | ||||
-rw-r--r-- | mysql-test/main/derived_split_innodb.test | 41 | ||||
-rw-r--r-- | mysql-test/main/lock_kill.test | 4 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/opt_split.cc | 27 | ||||
-rw-r--r-- | storage/innobase/include/srv0mon.h | 2 | ||||
-rw-r--r-- | storage/innobase/page/page0cur.cc | 12 |
8 files changed, 141 insertions, 14 deletions
diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 33b625a0f6d..016ca22af1b 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -16679,7 +16679,7 @@ EXPLAIN EXTENDED SELECT * FROM v1 JOIN v2 ON v1.f = v2.f; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -3 LATERAL DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table +3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table Warnings: Note 1003 /* select#1 */ select NULL AS `f`,`v2`.`f` AS `f` from `test`.`t1` `a` straight_join `test`.`t1` `b` join `test`.`v2` where 0 DROP VIEW v1,v2; diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 55ace91507e..9edf9a1f2ae 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -176,3 +176,68 @@ id select_type table type possible_keys key key_len ref rows Extra 3 LATERAL DERIVED t1 ref a,a_2 a 5 test.t1.a 1 Using where; Using temporary; Using filesort 3 LATERAL DERIVED t2 ref c c 5 test.t1.b 1 Using index DROP TABLE t1, t2; +# +# Bug mdev-25714: usage non-splitting covering index is cheaper than +# usage of the best splitting index for one group +# +create table t1 ( +id int not null, itemid int not null, index idx (itemid) +) engine=innodb; +insert into t1 values (1, 2), (2,2), (4,2), (4,2), (0,3), (3,3); +create table t2 (id int not null) engine=innodb; +insert into t2 values (2); +create table t3 ( +id int not null, itemid int not null, userid int not null, primary key (id), +index idx1 (userid, itemid), index idx2 (itemid) +) engine innodb; +insert into t3 values (1,1,1), (2,1,1), (3,2,1), (4,2,1), (5,3,1); +set use_stat_tables='never'; +set optimizer_use_condition_selectivity=1; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status OK +test.t2 analyze status OK +test.t3 analyze status OK +set optimizer_switch='split_materialized=on'; +explain select t1.id, t1.itemid, dt.id, t2.id +from t1, +(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt, +t2 +where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2 +1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +2 DERIVED t3 ref idx1,idx2 idx1 4 const 5 Using where; Using index +select t1.id, t1.itemid, dt.id, t2.id +from t1, +(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt, +t2 +where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; +id itemid id id +4 2 4 2 +4 2 4 2 +set optimizer_switch='split_materialized=off'; +explain select t1.id, t1.itemid, dt.id, t2.id +from t1, +(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt, +t2 +where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 1 +1 PRIMARY <derived2> ref key1 key1 4 test.t2.id 2 +1 PRIMARY t1 ALL idx NULL NULL NULL 6 Using where; Using join buffer (flat, BNL join) +2 DERIVED t3 ref idx1 idx1 4 const 5 Using where; Using index +select t1.id, t1.itemid, dt.id, t2.id +from t1, +(select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt, +t2 +where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; +id itemid id id +4 2 4 2 +4 2 4 2 +drop table t1,t2,t3; +set optimizer_switch='split_materialized=default'; +set use_stat_tables=default; +set optimizer_use_condition_selectivity=default; +# End of 10.3 tests diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index 10fc3f93190..bee9ef497b6 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -152,3 +152,44 @@ eval set statement optimizer_switch='split_materialized=on' for $query; DROP TABLE t1, t2; +--echo # +--echo # Bug mdev-25714: usage non-splitting covering index is cheaper than +--echo # usage of the best splitting index for one group +--echo # + +create table t1 ( + id int not null, itemid int not null, index idx (itemid) +) engine=innodb; +insert into t1 values (1, 2), (2,2), (4,2), (4,2), (0,3), (3,3); +create table t2 (id int not null) engine=innodb; +insert into t2 values (2); +create table t3 ( + id int not null, itemid int not null, userid int not null, primary key (id), + index idx1 (userid, itemid), index idx2 (itemid) +) engine innodb; +insert into t3 values (1,1,1), (2,1,1), (3,2,1), (4,2,1), (5,3,1); +set use_stat_tables='never'; +set optimizer_use_condition_selectivity=1; +analyze table t1,t2,t3; + +let $q= +select t1.id, t1.itemid, dt.id, t2.id + from t1, + (select itemid, max(id) as id from t3 where userid = 1 group by itemid) dt, + t2 + where t1.id = dt.id and t1.itemid = dt.itemid and t2.id=t1.itemid; + +set optimizer_switch='split_materialized=on'; +eval explain $q; +eval $q; + +set optimizer_switch='split_materialized=off'; +eval explain $q; +eval $q; + +drop table t1,t2,t3; +set optimizer_switch='split_materialized=default'; +set use_stat_tables=default; +set optimizer_use_condition_selectivity=default; + +--echo # End of 10.3 tests diff --git a/mysql-test/main/lock_kill.test b/mysql-test/main/lock_kill.test index dfeebbc4f6a..2c1396e5ff3 100644 --- a/mysql-test/main/lock_kill.test +++ b/mysql-test/main/lock_kill.test @@ -17,7 +17,7 @@ LOCK TABLE t1 WRITE; eval KILL $conid; --enable_query_log --connection con1 ---error 0,2013,ER_CONNECTION_KILLED +--error 0,2006,2013,ER_CONNECTION_KILLED reap; --connection default --disconnect con1 @@ -35,7 +35,7 @@ LOCK TABLE t1 WRITE, t2 WRITE; eval KILL $conid; --enable_query_log --connection con1 ---error 0,2013,ER_CONNECTION_KILLED +--error 0,2006,2013,ER_CONNECTION_KILLED reap; --connection default --disconnect con1 diff --git a/sql/field.cc b/sql/field.cc index f3deffccee5..ab4f6a96921 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7857,7 +7857,7 @@ bool Field_varstring::send(Protocol *protocol) #ifdef HAVE_MEM_CHECK void Field_varstring::mark_unused_memory_as_defined() { - uint used_length= get_length(); + uint used_length __attribute__((unused)) = get_length(); MEM_MAKE_DEFINED(get_data() + used_length, field_length - used_length); } #endif diff --git a/sql/opt_split.cc b/sql/opt_split.cc index 28a54838169..316919c4a81 100644 --- a/sql/opt_split.cc +++ b/sql/opt_split.cc @@ -958,11 +958,7 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, in the cache */ spl_plan= spl_opt_info->find_plan(best_table, best_key, best_key_parts); - if (!spl_plan && - (spl_plan= (SplM_plan_info *) thd->alloc(sizeof(SplM_plan_info))) && - (spl_plan->best_positions= - (POSITION *) thd->alloc(sizeof(POSITION) * join->table_count)) && - !spl_opt_info->plan_cache.push_back(spl_plan)) + if (!spl_plan) { /* The plan for the chosen key has not been found in the cache. @@ -972,6 +968,27 @@ SplM_plan_info * JOIN_TAB::choose_best_splitting(double record_count, reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table, best_key, remaining_tables, true); choose_plan(join, all_table_map & ~join->const_table_map); + + /* + Check that the chosen plan is really a splitting plan. + If not or if there is not enough memory to save the plan in the cache + then just return with no splitting plan. + */ + POSITION *first_non_const_pos= join->best_positions + join->const_tables; + TABLE *table= first_non_const_pos->table->table; + key_map spl_keys= table->keys_usable_for_splitting; + if (!(first_non_const_pos->key && + spl_keys.is_set(first_non_const_pos->key->key)) || + !(spl_plan= (SplM_plan_info *) thd->alloc(sizeof(SplM_plan_info))) || + !(spl_plan->best_positions= + (POSITION *) thd->alloc(sizeof(POSITION) * join->table_count)) || + spl_opt_info->plan_cache.push_back(spl_plan)) + { + reset_validity_vars_for_keyuses(best_key_keyuse_ext_start, best_table, + best_key, remaining_tables, false); + return 0; + } + spl_plan->keyuse_ext_start= best_key_keyuse_ext_start; spl_plan->table= best_table; spl_plan->key= best_key; diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h index 77a90b0c84a..cbda9d06338 100644 --- a/storage/innobase/include/srv0mon.h +++ b/storage/innobase/include/srv0mon.h @@ -639,7 +639,7 @@ Use MONITOR_DEC if appropriate mutex protection exists. #ifdef HAVE_MEM_CHECK # define MONITOR_CHECK_DEFINED(value) do { \ - mon_type_t m = value; \ + mon_type_t m __attribute__((unused))= value; \ MEM_CHECK_DEFINED(&m, sizeof m); \ } while (0) #else /* HAVE_MEM_CHECK */ diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index f75d1a8be77..cc6b1797d61 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -1315,8 +1315,10 @@ page_cur_insert_rec_low( #ifdef HAVE_MEM_CHECK { - const void *rec_start= rec - rec_offs_extra_size(offsets); - ulint extra_size= rec_offs_extra_size(offsets) - + const void *rec_start __attribute__((unused))= + rec - rec_offs_extra_size(offsets); + ulint extra_size __attribute__((unused))= + rec_offs_extra_size(offsets) - (page_is_comp(block->frame) ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES); @@ -1722,8 +1724,10 @@ page_cur_insert_rec_zip( #ifdef HAVE_MEM_CHECK { - const void *rec_start= rec - rec_offs_extra_size(offsets); - ulint extra_size= rec_offs_extra_size(offsets) - REC_N_NEW_EXTRA_BYTES; + const void *rec_start __attribute__((unused))= + rec - rec_offs_extra_size(offsets); + ulint extra_size __attribute__((unused))= + rec_offs_extra_size(offsets) - REC_N_NEW_EXTRA_BYTES; /* All data bytes of the record must be valid. */ MEM_CHECK_DEFINED(rec, rec_offs_data_size(offsets)); /* The variable-length header must be valid. */ |