Browse Source

BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT

- Enable subquery materialization for CREATE TABLE ... SELECT.
pull/843/head
Sergey Petrunya 14 years ago
parent
commit
8871806788
  1. 19
      mysql-test/r/subselect_sj_mat.result
  2. 14
      mysql-test/t/subselect_sj_mat.test
  3. 7
      sql/opt_subselect.cc

19
mysql-test/r/subselect_sj_mat.result

@ -1898,6 +1898,25 @@ WHERE 'condition'='impossible'
MIN(a)
NULL
DROP TABLE t1;
#
# BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
#
CREATE TABLE t1(a int);
INSERT INTO t1 values(1),(2);
CREATE TABLE t2(a int);
INSERT INTO t2 values(1),(2);
# Should use Materialization:
EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 test.t1.a 1
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using temporary
flush status;
CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
SHOW STATUS LIKE 'Created_tmp_tables';
Variable_name Value
Created_tmp_tables 2
DROP TABLE t1,t2,t3;
# This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level;

14
mysql-test/t/subselect_sj_mat.test

@ -1559,6 +1559,20 @@ WHERE a IN (
DROP TABLE t1;
--echo #
--echo # BUG#938131: Subquery materialization is not used in CREATE TABLE SELECT
--echo #
CREATE TABLE t1(a int);
INSERT INTO t1 values(1),(2);
CREATE TABLE t2(a int);
INSERT INTO t2 values(1),(2);
--echo # Should use Materialization:
EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
flush status;
CREATE TABLE t3 SELECT * FROM t1 WHERE a IN (SELECT * FROM t2 GROUP BY a HAVING a > 1);
SHOW STATUS LIKE 'Created_tmp_tables';
DROP TABLE t1,t2,t3;
--echo # This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level;

7
sql/opt_subselect.cc

@ -251,8 +251,8 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
Subquery !contains {GROUP BY, ORDER BY [LIMIT],
aggregate functions}) && subquery predicate is not under "NOT IN"))
(*) The subquery must be part of a SELECT statement. The current
condition also excludes multi-table update statements.
(*) 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.
@ -261,7 +261,8 @@ bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
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_SELECT || // *
thd->lex->sql_command == SQLCOM_CREATE_TABLE) && // *
child_select->outer_select()->leaf_tables.elements && // 2A
subquery_types_allow_materialization(in_subs) &&
(in_subs->is_top_level_item() || //3

Loading…
Cancel
Save