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) MIN(a)
NULL NULL
DROP TABLE t1; 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: # This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp; set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level; 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; 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: --echo # This must be at the end:
set optimizer_switch=@subselect_sj_mat_tmp; set optimizer_switch=@subselect_sj_mat_tmp;
set join_cache_level=@save_join_cache_level; 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], Subquery !contains {GROUP BY, ORDER BY [LIMIT],
aggregate functions}) && subquery predicate is not under "NOT IN")) 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 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 PREPARE and each EXECUTE. The rewrites are only done once, but we need
select_lex->sj_subselects list to be populated for every EXECUTE. 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 if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
!child_select->is_part_of_union() && // 1 !child_select->is_part_of_union() && // 1
parent_unit->first_select()->leaf_tables.elements && // 2 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 child_select->outer_select()->leaf_tables.elements && // 2A
subquery_types_allow_materialization(in_subs) && subquery_types_allow_materialization(in_subs) &&
(in_subs->is_top_level_item() || //3 (in_subs->is_top_level_item() || //3

Loading…
Cancel
Save