Commit d67ec38c authored by Igor Babaev's avatar Igor Babaev

Merge

parents 1783f4de 2e527460
......@@ -5313,4 +5313,83 @@ a b c d
SET SESSION join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
#
# Bug #901478: semijoin + ORDER BY + join_cache_level=4|6
#
CREATE TABLE t1 (a char(1));
INSERT INTO t1 VALUES ('x');
CREATE TABLE t2 (a int, b int, c int, KEY(a), KEY(b), KEY(c));
INSERT INTO t2 VALUES
(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
CREATE TABLE t3 (a CHAR(1));
INSERT INTO t3 VALUES ('x');
CREATE TABLE t4 (a int, b int, c int, KEY(b), KEY(c));
INSERT INTO t4 VALUES
(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
INSERT INTO t4 VALUES
(19,11,10), (17,12,18), (12,13,15), (14,12,19),
(18,13,18), (13,14,11), (15,15,14);
SET @tmp_optimizer_switch=@@optimizer_switch;
SET @@optimizer_switch='semijoin=on';
SET @@optimizer_switch='firstmatch=off';
SET @@optimizer_switch='mrr=off';
SET @@optimizer_switch='semijoin_with_cache=off';
set join_cache_level=1;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using filesort
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
a a b c
x 4 2 9
x 5 5 4
set join_cache_level=4;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
a a b c
x 4 2 9
x 5 5 4
SET @@optimizer_switch='semijoin_with_cache=on';
set join_cache_level=6;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY t2 range a,c a 5 NULL 1 Using index condition; Using where
1 PRIMARY t4 ref c c 5 test.t2.c 2 Using where; Start temporary; End temporary
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
a a b c
x 4 2 9
x 5 5 4
SET join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3,t4;
set @@optimizer_switch=@save_optimizer_switch;
......@@ -3361,5 +3361,68 @@ SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3;
--echo #
--echo # Bug #901478: semijoin + ORDER BY + join_cache_level=4|6
--echo #
CREATE TABLE t1 (a char(1));
INSERT INTO t1 VALUES ('x');
CREATE TABLE t2 (a int, b int, c int, KEY(a), KEY(b), KEY(c));
INSERT INTO t2 VALUES
(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
CREATE TABLE t3 (a CHAR(1));
INSERT INTO t3 VALUES ('x');
CREATE TABLE t4 (a int, b int, c int, KEY(b), KEY(c));
INSERT INTO t4 VALUES
(9,1,0), (7,2,8), (2,3,5), (4,2,9), (8,3,8), (3,4,1), (5,5,4);
INSERT INTO t4 VALUES
(19,11,10), (17,12,18), (12,13,15), (14,12,19),
(18,13,18), (13,14,11), (15,15,14);
SET @tmp_optimizer_switch=@@optimizer_switch;
SET @@optimizer_switch='semijoin=on';
SET @@optimizer_switch='firstmatch=off';
SET @@optimizer_switch='mrr=off';
SET @@optimizer_switch='semijoin_with_cache=off';
set join_cache_level=1;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
set join_cache_level=4;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
SET @@optimizer_switch='semijoin_with_cache=on';
set join_cache_level=6;
EXPLAIN
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
SELECT * FROM t1,t2
WHERE t2.c IN (SELECT c FROM t3,t4 WHERE t4.a < 10) AND
t2.a BETWEEN 4 and 5
ORDER BY t2.b;
SET join_cache_level = DEFAULT;
SET optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2,t3,t4;
# this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch;
......@@ -4138,6 +4138,16 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
{
/* Looks like we'll be using join buffer */
first_table= join->const_tables;
/*
Make sure that possible sorting of rows from the head table
is not to be employed.
*/
if (join->get_sort_by_join_tab())
{
join->simple_order= 0;
join->simple_group= 0;
join->need_tmp= join->test_if_need_tmp_table();
}
break;
}
}
......
......@@ -1525,22 +1525,7 @@ JOIN::optimize()
}
}
/*
Check if we need to create a temporary table.
This has to be done if all tables are not already read (const tables)
and one of the following conditions holds:
- We are using DISTINCT (simple distinct's are already optimized away)
- We are using an ORDER BY or GROUP BY on fields not in the first table
- We are using different ORDER BY and GROUP BY orders
- The user wants us to buffer the result.
When the WITH ROLLUP modifier is present, we cannot skip temporary table
creation for the DISTINCT clause just because there are only const tables.
*/
need_tmp= ((const_tables != table_count &&
((select_distinct || !simple_order || !simple_group) ||
(group_list && order) ||
test(select_options & OPTION_BUFFER_RESULT))) ||
(rollup.state != ROLLUP::STATE_NONE && select_distinct));
need_tmp= test_if_need_tmp_table();
/*
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
......
......@@ -1319,6 +1319,25 @@ class JOIN :public Sql_alloc
return test(allowed_join_cache_types & JOIN_CACHE_HASHED_BIT) &&
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
}
/*
Check if we need to create a temporary table.
This has to be done if all tables are not already read (const tables)
and one of the following conditions holds:
- We are using DISTINCT (simple distinct's are already optimized away)
- We are using an ORDER BY or GROUP BY on fields not in the first table
- We are using different ORDER BY and GROUP BY orders
- The user wants us to buffer the result.
When the WITH ROLLUP modifier is present, we cannot skip temporary table
creation for the DISTINCT clause just because there are only const tables.
*/
bool test_if_need_tmp_table()
{
return ((const_tables != table_count &&
((select_distinct || !simple_order || !simple_group) ||
(group_list && order) ||
test(select_options & OPTION_BUFFER_RESULT))) ||
(rollup.state != ROLLUP::STATE_NONE && select_distinct));
}
bool choose_subquery_plan(table_map join_tables);
void get_partial_cost_and_fanout(int end_tab_idx,
table_map filter_map,
......
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