Commit 74b43628 authored by Sergey Petrunya's avatar Sergey Petrunya

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

- Enable subquery materialization for CREATE TABLE ... SELECT.
parent 09dd66eb
......@@ -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;
......@@ -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;
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment