[Commits] Rev 4518: MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT in file:///home/psergey/dev2/10.0/

Sergey Petrunya psergey at askmonty.org
Wed Nov 26 19:30:56 EET 2014


At file:///home/psergey/dev2/10.0/

------------------------------------------------------------
revno: 4518
revision-id: psergey at askmonty.org-20141126173051-v1mumlrmzb8lx9xh
parent: jplindst at mariadb.org-20141126123355-2yerm7dfu0tk5q7p
committer: Sergey Petrunya <psergey at askmonty.org>
branch nick: 10.0
timestamp: Wed 2014-11-26 20:30:51 +0300
message:
  MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
  - Enable subquery materialization for non-SELECT queries.
=== modified file 'mysql-test/r/subselect_mat.result'
--- a/mysql-test/r/subselect_mat.result	2014-08-07 16:06:56 +0000
+++ b/mysql-test/r/subselect_mat.result	2014-11-26 17:30:51 +0000
@@ -2146,6 +2146,57 @@ drop database mysqltest2;
 drop database mysqltest3;
 drop database mysqltest4;
 # End of 5.5 tests
+#
+# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1 
+select A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100
+from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, c int);
+insert into t2 select A.a, A.a, A.a from t1 A;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+create table t3 as select * from t2 limit 1;
+# The testcase only makes sense if the following uses Materialization:
+explain
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+1	PRIMARY	<subquery2>	eq_ref	distinct_key	distinct_key	8	test.t1.a,test.t1.b	1	
+2	MATERIALIZED	t2	ALL	NULL	NULL	NULL	NULL	4000	Using temporary
+flush status;
+replace into t3 
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+#  Sequential reads:
+#    1K is read from t1
+#    4K is read from t2
+#    1K groups is read from the tmp. table
+#
+#  Lookups:
+#    4K lookups in group by table
+#    1K lookups in temp.table
+#
+#  Writes:
+#    2x 1K writes to temporary tables (grouping table and subquery materialization table
+#
+#  The point is that neither counter should be in the millions (this
+#     will happen if Materialization is not used 
+show status where Variable_name like 'Handler_read%' or  Variable_name like 'Handler_%write%';
+Variable_name	Value
+Handler_read_first	0
+Handler_read_key	5000
+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	6003
+Handler_tmp_write	2000
+Handler_write	1000
+drop table t0,t1,t2,t3;
 set @subselect_mat_test_optimizer_switch_value=null;
 set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
 set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';

=== modified file 'mysql-test/r/subselect_sj_mat.result'
--- a/mysql-test/r/subselect_sj_mat.result	2014-08-07 16:06:56 +0000
+++ b/mysql-test/r/subselect_sj_mat.result	2014-11-26 17:30:51 +0000
@@ -2186,3 +2186,54 @@ drop database mysqltest2;
 drop database mysqltest3;
 drop database mysqltest4;
 # End of 5.5 tests
+#
+# MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a int, b int, c int);
+insert into t1 
+select A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100
+from t0 A, t0 B, t0 C;
+create table t2 (a int, b int, c int);
+insert into t2 select A.a, A.a, A.a from t1 A;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+create table t3 as select * from t2 limit 1;
+# The testcase only makes sense if the following uses Materialization:
+explain
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	1000	Using where
+1	PRIMARY	<subquery2>	eq_ref	distinct_key	distinct_key	8	test.t1.a,test.t1.b	1	
+2	MATERIALIZED	t2	ALL	NULL	NULL	NULL	NULL	4000	Using temporary
+flush status;
+replace into t3 
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+#  Sequential reads:
+#    1K is read from t1
+#    4K is read from t2
+#    1K groups is read from the tmp. table
+#
+#  Lookups:
+#    4K lookups in group by table
+#    1K lookups in temp.table
+#
+#  Writes:
+#    2x 1K writes to temporary tables (grouping table and subquery materialization table
+#
+#  The point is that neither counter should be in the millions (this
+#     will happen if Materialization is not used 
+show status where Variable_name like 'Handler_read%' or  Variable_name like 'Handler_%write%';
+Variable_name	Value
+Handler_read_first	0
+Handler_read_key	5000
+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	6003
+Handler_tmp_write	2000
+Handler_write	1000
+drop table t0,t1,t2,t3;

=== modified file 'mysql-test/t/subselect_sj_mat.test'
--- a/mysql-test/t/subselect_sj_mat.test	2014-08-07 16:06:56 +0000
+++ b/mysql-test/t/subselect_sj_mat.test	2014-11-26 17:30:51 +0000
@@ -1843,3 +1843,45 @@ drop database mysqltest4;
 
 --echo # End of 5.5 tests
 
+--echo #
+--echo # MDEV-7220: Materialization strategy is not used for REPLACE ... SELECT
+--echo #
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (a int, b int, c int);
+insert into t1 
+select A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100, A.a+B.a*10+C.a*100
+from t0 A, t0 B, t0 C;
+
+create table t2 (a int, b int, c int);
+insert into t2 select A.a, A.a, A.a from t1 A;
+insert into t2 select * from t2;
+insert into t2 select * from t2;
+
+create table t3 as select * from t2 limit 1;
+
+--echo # The testcase only makes sense if the following uses Materialization:
+explain
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+
+flush status;
+replace into t3 
+select * from t1 where (a,b) in (select max(a),b from t2 group by b);
+--echo #  Sequential reads:
+--echo #    1K is read from t1
+--echo #    4K is read from t2
+--echo #    1K groups is read from the tmp. table
+--echo #
+--echo #  Lookups:
+--echo #    4K lookups in group by table
+--echo #    1K lookups in temp.table
+--echo #
+--echo #  Writes:
+--echo #    2x 1K writes to temporary tables (grouping table and subquery materialization table
+--echo #
+--echo #  The point is that neither counter should be in the millions (this
+--echo #     will happen if Materialization is not used 
+show status where Variable_name like 'Handler_read%' or  Variable_name like 'Handler_%write%';
+
+drop table t0,t1,t2,t3;

=== modified file 'sql/opt_subselect.cc'
--- a/sql/opt_subselect.cc	2014-09-30 17:31:14 +0000
+++ b/sql/opt_subselect.cc	2014-11-26 17:30:51 +0000
@@ -513,8 +513,6 @@ bool is_materialization_applicable(THD *
          Subquery !contains {GROUP BY, ORDER BY [LIMIT],
          aggregate functions}) && subquery predicate is not under "NOT IN"))
 
-    (*) The subquery must be part of a SELECT or CREATE TABLE ... SELECT statement.
-        The current condition also excludes multi-table update statements.
   A note about prepared statements: we want the if-branch to be taken on
   PREPARE and each EXECUTE. The rewrites are only done once, but we need 
   select_lex->sj_subselects list to be populated for every EXECUTE. 
@@ -523,9 +521,7 @@ bool is_materialization_applicable(THD *
   if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) &&      // 0
         !child_select->is_part_of_union() &&                          // 1
         parent_unit->first_select()->leaf_tables.elements &&          // 2
-        (thd->lex->sql_command == SQLCOM_SELECT ||                     // *
-         thd->lex->sql_command == SQLCOM_CREATE_TABLE) &&              // *
-        child_select->outer_select()->leaf_tables.elements &&           // 2A
+        child_select->outer_select()->leaf_tables.elements &&         // 2A
         subquery_types_allow_materialization(in_subs) &&
         (in_subs->is_top_level_item() ||                               //3
          optimizer_flag(thd,



More information about the commits mailing list