mirror of
https://github.com/MariaDB/server.git
synced 2025-04-07 15:55:41 +02:00
1856 lines
120 KiB
Text
1856 lines
120 KiB
Text
CREATE TABLE t1 (a INTEGER NOT NULL, b INT, PRIMARY KEY (a));
|
|
CREATE TABLE t2 (a INTEGER NOT NULL, KEY (a));
|
|
CREATE TABLE t3 (a INTEGER NOT NULL, b INT, KEY (a));
|
|
INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
|
|
INSERT INTO t2 VALUES (2), (3), (4), (5);
|
|
INSERT INTO t3 VALUES (10,3), (20,4), (30,5);
|
|
ANALYZE TABLE t1, t2, t3;
|
|
Table Op Msg_type Msg_text
|
|
test.t1 analyze status Engine-independent statistics collected
|
|
test.t1 analyze status OK
|
|
test.t2 analyze status Engine-independent statistics collected
|
|
test.t2 analyze status OK
|
|
test.t3 analyze status Engine-independent statistics collected
|
|
test.t3 analyze status OK
|
|
# Parser tests
|
|
# Correct hints (no warnings):
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN() */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`select#1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) SEMIJOIN(@qb1) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SEMIJOIN(@`qb1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) NO_SEMIJOIN(@qb1 firstmatch) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ QB_NAME(`qb1`) NO_SEMIJOIN(@`qb1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) SEMIJOIN( @qb1 firstmatch, dupsweedout ) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SEMIJOIN(@`qb1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN( FIRSTMATCH, LOOSESCAN,materialization, DUPSWEEDOUT ) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`select#1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb2) NO_SEMIJOIN(@qb2 FIRSTMATCH,LOOSESCAN, materialization, DUPSWEEDOUT) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ QB_NAME(`qb2`) NO_SEMIJOIN(@`qb2` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
set optimizer_switch='derived_merge=off';
|
|
# Correct 'cause hints refer to different query blocks:
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@qb1) SEMIJOIN(loosescan)*/ a
|
|
FROM (SELECT /*+ QB_NAME(qb1)*/ * FROM t2) AS tt;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
|
2 DERIVED t2 index NULL a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`qb1`) SEMIJOIN(@`select#1` LOOSESCAN) */ `tt`.`a` AS `a` from (/* select#2 */ select /*+ QB_NAME(`qb1`) */ `test`.`t2`.`a` AS `a` from `test`.`t2`) `tt`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN()*/ a
|
|
FROM (SELECT /*+ SEMIJOIN(loosescan)*/ * FROM t2) AS tt;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
|
2 DERIVED t2 index NULL a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`select#2` LOOSESCAN) SEMIJOIN(@`select#1`) */ `tt`.`a` AS `a` from (/* select#2 */ select `test`.`t2`.`a` AS `a` from `test`.`t2`) `tt`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(materialization) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY( INTOEXISTS ) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` INTOEXISTS) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME (qb1) SUBQUERY(@qb1 materialization) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SUBQUERY(@`qb1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
# Incorrect hints (warnings)
|
|
SELECT /*+ SEMIJOIN(loosescan @qb1) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near '@qb1) */ a FROM t1' at line 1
|
|
SELECT /*+ SEMIJOIN(@qb1 @qb2) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near '@qb2) */ a FROM t1' at line 1
|
|
SELECT /*+ SEMIJOIN(@qb1 LOOSESCAN,materialization, unknown_strategy) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near 'unknown_strategy) */ a FROM t1' at line 1
|
|
SELECT /*+ NO_SEMIJOIN(@qb1, @qb2) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ', @qb2) */ a FROM t1' at line 1
|
|
SELECT /*+ NO_SEMIJOIN(FIRSTMATCH, ,LOOSESCAN, materialization) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ',LOOSESCAN, materialization) */ a FROM t1' at line 1
|
|
SELECT /*+ NO_SEMIJOIN(FIRSTMATCH, @qb2,LOOSESCAN) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near '@qb2,LOOSESCAN) */ a FROM t1' at line 1
|
|
SELECT /*+ SUBQUERY(wrong_strat) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near 'wrong_strat) */ a FROM t1' at line 1
|
|
SELECT /*+ SUBQUERY(materialization, intoexists) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ', intoexists) */ a FROM t1' at line 1
|
|
SELECT /*+ SUBQUERY(@qb1 materialization) */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 4212 Query block name `qb1` is not found for SUBQUERY hint
|
|
SELECT /*+ SUBQUERY() */ a FROM t1;
|
|
a
|
|
1
|
|
2
|
|
3
|
|
4
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ') */ a FROM t1' at line 1
|
|
# Mix of correct and incorrect hints:
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(firstmatch ) SEMIJOIN(loosescan @qb1) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near '@qb1) */ a FROM t1' at line 2
|
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@qb1, @qb2) SEMIJOIN()*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ', @qb2) SEMIJOIN()*/ a FROM t1' at line 2
|
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN() NO_SEMIJOIN(FIRSTMATCH, @qb2,LOOSESCAN) */ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near '@qb2,LOOSESCAN) */ a FROM t1' at line 2
|
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
# Conflicting hints:
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN() SEMIJOIN(dupsweedout) NO_SEMIJOIN(firstmatch)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(DUPSWEEDOUT) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint NO_SEMIJOIN(FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`select#1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(loosescan,materialization) SEMIJOIN(dupsweedout)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(DUPSWEEDOUT) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`select#1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(firstmatch,loosescan,materialization) SEMIJOIN() NO_SEMIJOIN()*/ a
|
|
FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN() is ignored as conflicting/duplicated
|
|
Warning 4211 Hint NO_SEMIJOIN() is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`select#1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) SEMIJOIN(@qb1) SEMIJOIN(loosescan) NO_SEMIJOIN(@qb1 dupsweedout)*/ a
|
|
FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(LOOSESCAN) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint NO_SEMIJOIN(@`qb1` DUPSWEEDOUT) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SEMIJOIN(@`qb1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED SELECT /*+ SEMIJOIN(firstmatch) NO_SEMIJOIN()*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN() is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`select#1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(materialization) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN() SUBQUERY(materialization) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`select#1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(materialization) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(materialization) SUBQUERY(intoexists) SUBQUERY(materialization)*/ a
|
|
FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SUBQUERY(MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(materialization) SEMIJOIN(firstmatch) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SUBQUERY(@`select#1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) SEMIJOIN(@qb1) SUBQUERY(@qb1 materialization) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(@`qb1` MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SEMIJOIN(@`qb1`) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ QB_NAME(qb1) SUBQUERY(@qb1 materialization) SEMIJOIN(@qb1 firstmatch) SUBQUERY(intoexists)*/ a FROM t1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`qb1` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ QB_NAME(`qb1`) SUBQUERY(@`qb1` MATERIALIZATION) */ `test`.`t1`.`a` AS `a` from `test`.`t1`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@qb1) SEMIJOIN(loosescan) NO_SEMIJOIN(@qb1 dupsweedout)*/ a
|
|
FROM (SELECT /*+ QB_NAME(qb1)*/ * FROM t2) AS tt;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 100.00
|
|
2 DERIVED t2 index NULL a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN(@`qb1` DUPSWEEDOUT) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`qb1`) SEMIJOIN(@`select#1` LOOSESCAN) */ `tt`.`a` AS `a` from (/* select#2 */ select /*+ QB_NAME(`qb1`) */ `test`.`t2`.`a` AS `a` from `test`.`t2`) `tt`
|
|
DROP TABLE t1, t2 ,t3;
|
|
set optimizer_switch=default;
|
|
# End of parser tests
|
|
CREATE TABLE t1 (a INTEGER NOT NULL, b INT, PRIMARY KEY (a));
|
|
CREATE TABLE t2 (a INTEGER NOT NULL, KEY (a));
|
|
CREATE TABLE t3 (a INTEGER NOT NULL, b INT, KEY (a));
|
|
INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
|
|
INSERT INTO t2 VALUES (2), (2), (3), (3), (4), (5);
|
|
INSERT INTO t3 VALUES (10,3), (15,3), (20,4), (30,5);
|
|
ANALYZE TABLE t1, t2, t3;
|
|
Table Op Msg_type Msg_text
|
|
test.t1 analyze status Engine-independent statistics collected
|
|
test.t1 analyze status OK
|
|
test.t2 analyze status Engine-independent statistics collected
|
|
test.t2 analyze status OK
|
|
test.t3 analyze status Engine-independent statistics collected
|
|
test.t3 analyze status OK
|
|
# This query will normally use Table Pull-out
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
# Check that we can disable SEMIJOIN transformation
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Same with hint in outer query
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Query with two sub-queries
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT a FROM t1 tx)
|
|
AND t3.b IN (SELECT a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and `test`.`ty`.`a` = `test`.`t3`.`b`
|
|
# No SEMIJOIN transformation for first subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where `test`.`ty`.`a` = `test`.`t3`.`b` and <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY))))
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(`subq1`) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where `test`.`ty`.`a` = `test`.`t3`.`b` and <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY))))
|
|
# No SEMIJOIN transformation for latter subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#3`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`b`) in t1 on PRIMARY))))
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@`subq2`) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`b`) in t1 on PRIMARY))))
|
|
# No SEMIJOIN transformation for any subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ NO_SEMIJOIN() */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) NO_SEMIJOIN(@`select#3`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY)))) and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`b`) in t1 on PRIMARY))))
|
|
EXPLAIN
|
|
SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 Using index
|
|
# Query with nested sub-queries
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`ty`.`a` = `test`.`tx`.`b` and `test`.`tx`.`a` = `test`.`t3`.`a`
|
|
# No SEMIJOIN transformation for outer subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 DEPENDENT SUBQUERY tx eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where
|
|
2 DEPENDENT SUBQUERY ty eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`tx`.`a` from `test`.`t1` `ty` join `test`.`t1` `tx` where `test`.`ty`.`a` = `test`.`tx`.`b` and <cache>(`test`.`t3`.`a`) = `test`.`tx`.`a`)))
|
|
# No SEMIJOIN transformation for inner-most subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and <expr_cache><`test`.`tx`.`b`>(<in_optimizer>(`test`.`tx`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`tx`.`b`) in t1 on PRIMARY))))
|
|
# No SEMIJOIN transformation at all
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1) NO_SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq2`) NO_SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY where <in_optimizer>(`test`.`tx`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`tx`.`b`) in t1 on PRIMARY))) and <cache>(`test`.`t3`.`a`) = `test`.`tx`.`a`))))
|
|
# This query does not support SEMIJOIN. SEMIJOIN hint is ignored
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 4 100.00
|
|
1 PRIMARY t2 ref a a 4 <subquery2>.min(a) 1 100.00 Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t2` where `test`.`t2`.`a` = `<subquery2>`.`min(a)`
|
|
# This query will get LooseScan by default
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Let's turn off LooseScan, FirstMatch is then SELECTed
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# Let's also turn off FirstMatch, DupsWeedout is then used.
|
|
# (StartTemporary, EndTemporary) in the output indicate DupsWeedout usage
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Materialization is used here
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where 1
|
|
# Turn off all strategies, DuplicateWeedout should be used as a fallback
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, MATERIALIZATION,
|
|
DUPSWEEDOUT) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Turn off non-used strategies, nothing should change. Still Loosescan
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Test same query with SEMIJOIN hint
|
|
# Forcing LooseScan, should not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Force FirstMatch
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# Force Materialization
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where 1
|
|
# Force DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# If LooseScan is among candidates, it will be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION,
|
|
DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Drop LooseScan from list of strategies, FirstMatch will be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
For this query LooseScan and Materialization is not applicable
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.b 1 100.00 Using where; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` = `test`.`t1`.`b`
|
|
# Turn off all applicable strategies. DuplicateWeedout should be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
# Similar with SEMIJOIN hint
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
# Test multiple subqueries.
|
|
# Default for this query is Loosecan for first and FirstMatch for latter
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Forcing the default strategy should not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Forcing a strategy for one, may change the other due to cost changes
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t3)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Forcing same strategy for both
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t3)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Loosescan for both is not possible, ends up with DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Swap strategies compared to default
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Different subsets of strategies for different subqueries
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN)
|
|
SEMIJOIN(@subq2 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) SEMIJOIN(@`subq2` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Vice versa
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT)
|
|
SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Another combination
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, FIRSTMATCH)
|
|
SEMIJOIN(@subq2 LOOSESCAN, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Turn off default
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN)
|
|
NO_SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Also turn off 2nd choice. Gives DuplicateWeedout over both
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH)
|
|
NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Also turn off DuplicateWeedout. Materialization is only one left.
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT)
|
|
NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where 1
|
|
# Force materialization with SEMIJOIN hints instead
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION)
|
|
SEMIJOIN(@subq2 MATERIALIZATION) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where 1
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION)
|
|
SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION)
|
|
SEMIJOIN(@subq2 LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch((sj-nest))
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` LOOSESCAN, FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# A query with nested subqueries which are joined together
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t3`.`a` = `test`.`t1`.`a`
|
|
# Let's turn off FirtMatch, DuplicateWeedout is then chosen
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 16.67 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t1`.`a` = `test`.`t3`.`a`
|
|
# If we turn off all strategies, DuplicateWeedout should still be used
|
|
EXPLAIN
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN, MATERIALIZATION,
|
|
DUPSWEEDOUT) */ *
|
|
FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 Using index; End temporary
|
|
# Test the same query with SEMIJOIN hint
|
|
# Force FirstMatch, should not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t3`.`a` = `test`.`t1`.`a`
|
|
# Force LooseScan, will fall back to DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 16.67 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t1`.`a` = `test`.`t3`.`a`
|
|
# Force DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 16.67 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t1`.`a` = `test`.`t3`.`a`
|
|
# If FirstMatch is among candidates, it will be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t3`.`a` = `test`.`t1`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION, FIRSTMATCH, LOOSESCAN,
|
|
DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3
|
|
WHERE t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t3.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION, FIRSTMATCH, LOOSESCAN, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`b` and `test`.`t3`.`a` = `test`.`t1`.`a`
|
|
# Test hints with prepared statements
|
|
PREPARE stmt1 FROM "EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN)
|
|
NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)";
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
DEALLOCATE PREPARE stmt1;
|
|
SET optimizer_switch = default;
|
|
# Tests with non-default optimizer_switch settings
|
|
SET optimizer_switch = 'semijoin=off';
|
|
# No table pull-out for this query
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# This should not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Force semijoin, table pull-out is performed
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
# Setting strategy should still force semijoin
|
|
# Strategy is ignored since table pull-out is done
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq FIRSTMATCH) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
# Query with two sub-queries
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT a FROM t1 tx)
|
|
AND t3.b IN (SELECT a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY)))) and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`b`) in t1 on PRIMARY))))
|
|
# SEMIJOIN transformation for first subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`b`) in t1 on PRIMARY))))
|
|
# SEMIJOIN transformation for latter subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t3` where `test`.`ty`.`a` = `test`.`t3`.`b` and <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY))))
|
|
# SEMIJOIN transformation for both subqueries
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1) SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1`) SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and `test`.`ty`.`a` = `test`.`t3`.`b`
|
|
# Query with nested sub-queries
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY where <in_optimizer>(`test`.`tx`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`tx`.`b`) in t1 on PRIMARY))) and <cache>(`test`.`t3`.`a`) = `test`.`tx`.`a`))))
|
|
# SEMIJOIN transformation for outer subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and <expr_cache><`test`.`tx`.`b`>(<in_optimizer>(`test`.`tx`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`tx`.`b`) in t1 on PRIMARY))))
|
|
# SEMIJOIN transformation for inner-most subquery
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 DEPENDENT SUBQUERY tx eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where
|
|
2 DEPENDENT SUBQUERY ty eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SEMIJOIN(@`subq2`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`tx`.`a` from `test`.`t1` `ty` join `test`.`t1` `tx` where `test`.`ty`.`a` = `test`.`tx`.`b` and <cache>(`test`.`t3`.`a`) = `test`.`tx`.`a`)))
|
|
# SEMIJOIN transformation for both
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1) SEMIJOIN(@subq2) */ * FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using where
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.tx.b 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq2`) SEMIJOIN(@`subq1`) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`ty`.`a` = `test`.`tx`.`b` and `test`.`tx`.`a` = `test`.`t3`.`a`
|
|
Test strategies when some are disabled by optimizer_switch
|
|
SET optimizer_switch='semijoin=on';
|
|
SET optimizer_switch='loosescan=off';
|
|
# This query will get LooseScan by default. FirstMatch now
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# Let's turn off LooseScan also by hint, FirstMatch is then selected
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# Let's also turn off FirstMatch, DupsWeedout is then used.
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Turn off DupsWeedout, Materialization is used here
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where 1
|
|
# Let's force LooseScan back on
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Forcing another strategy
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where 1
|
|
# If LooseScan is among candidates, it is used even if originally disabled
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION,
|
|
DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
Disable another strategy
|
|
SET optimizer_switch='firstmatch=off';
|
|
# Turn on FirstMatch, but not LooseScan on with hint
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# Drop all remaining strategies with hint, should use DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# For this query LooseScan and Materialization is not applicable
|
|
# Should use DuplicateWeedout since FirstMatch is disabled
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
Turn off all applicable strategies. DuplicateWeedout should still be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
Reverse which strategies are allowed with hint
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.b 1 100.00 Using where; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` = `test`.`t1`.`b`
|
|
# Default for this query is Loosecan for first and FirstMatch for latter
|
|
# Since both strategies are disabled, will now use DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Allowing LooseScan and FirstMatch and optimizer_switch is ignored
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH)
|
|
SEMIJOIN(@subq2 LOOSESCAN, FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN, FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Forcing a disabled strategy for one
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Forcing same strategy for both
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t3)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Swap strategies compared to default
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH) SEMIJOIN(@subq2 LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Different subsets of strategies for different subqueries
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN)
|
|
SEMIJOIN(@subq2 MATERIALIZATION, DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) SEMIJOIN(@`subq2` MATERIALIZATION, DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Turn off DuplicateWeedout for both. Materialization is left
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 DUPSWEEDOUT)
|
|
NO_SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` DUPSWEEDOUT) NO_SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where 1
|
|
# Forcing materialization should have same effect
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 MATERIALIZATION)
|
|
SEMIJOIN(@subq2 MATERIALIZATION) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` MATERIALIZATION) SEMIJOIN(@`subq2` MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where 1
|
|
# Turn off DuplicateWeedout for first. MatLookup is used for both
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Turn off DuplicateWeedout for second. Same effect.
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq2 DUPSWEEDOUT) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 End temporary
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq2` DUPSWEEDOUT) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a`
|
|
Enable all strategies except DuplicateWeedout
|
|
SET optimizer_switch='firstmatch=on,loosescan=on,materialization=on,duplicateweedout=off';
|
|
# If we turn off all other strategies, DuplicateWeedout will be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH, MATERIALIZATION) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# LooseScan and Materialization is not applicable, FirstMatch is used
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.b 1 100.00 Using where; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` = `test`.`t1`.`b`
|
|
# Turn off all applicable strategies. DuplicateWeedout should be used
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
# Similar with SEMIJOIN hint
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
# Disable all strategies
|
|
SET optimizer_switch='firstmatch=off,loosescan=off,materialization=off,duplicateweedout=off';
|
|
# DuplicateWeedout is then used
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Turning off extra strategies should not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN, DUPSWEEDOUT) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t2 ref a a 4 test.t3.a 1 25.00 Using index; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN, DUPSWEEDOUT) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t2`.`a` = `test`.`t3`.`a`
|
|
# Turning on some strategies should give one of those
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 FIRSTMATCH, MATERIALIZATION) */ *
|
|
FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index a a 4 NULL 6 100.00 Using index
|
|
1 PRIMARY t3 ref a a 4 test.t2.a 1 100.00 Using index; FirstMatch(t2)
|
|
Warnings:
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` FIRSTMATCH, MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t3`) where `test`.`t3`.`a` = `test`.`t2`.`a`
|
|
# For this query that cannot use LooseScan or Materialization,
|
|
# turning those on will still give DuplicateWeedout
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, MATERIALIZATION) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 25.00 Using where; End temporary
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, MATERIALIZATION) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t1`.`a` = `test`.`t3`.`b` and `test`.`t1`.`b` = `test`.`t3`.`a`
|
|
# Turning on FirstMatch should give FirstMatch
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN, FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.b IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3 WHERE t3.b = t1.a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.b 1 100.00 Using where; FirstMatch(t1)
|
|
Warnings:
|
|
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN, FIRSTMATCH) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) where `test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` = `test`.`t1`.`b`
|
|
SET optimizer_switch = default;
|
|
Test that setting optimizer_switch after prepare will change strategy
|
|
PREPARE stmt1 FROM "EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 FIRSTMATCH, LOOSESCAN)
|
|
NO_SEMIJOIN(@subq2 FIRSTMATCH, LOOSESCAN) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)";
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
SET optimizer_switch = 'duplicateweedout=off';
|
|
Will now use materialization
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00
|
|
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
|
2 MATERIALIZED t3 index a a 4 NULL 4 100.00 Using index
|
|
3 MATERIALIZED t2 index a a 4 NULL 6 100.00 Using index
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where 1
|
|
SET optimizer_switch = 'duplicateweedout=on';
|
|
Turn DuplicateWeedout back on
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; Start temporary
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where; End temporary
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` FIRSTMATCH, LOOSESCAN) NO_SEMIJOIN(@`subq2` FIRSTMATCH, LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
DEALLOCATE PREPARE stmt1;
|
|
SET optimizer_switch = default;
|
|
# Specifying two SEMIJOIN/NO_SEMIJOIN for same query block gives warning
|
|
# First has effect, second is ignored
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN() is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Try opposite order
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ SEMIJOIN() NO_SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN() is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
# Specify at different levels, hint inside block has effect
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
# Specify at different levels, opposite order
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Duplicate hints also gives warning, but hint has effect
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN(@`subq` ) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Multiple subqueries with conflicting hints
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) NO_SEMIJOIN() */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) SEMIJOIN(LOOSESCAN) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
2 DEPENDENT SUBQUERY t3 index_subquery a a 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SEMIJOIN(@`subq2` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq1`) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t2`) where `test`.`t2`.`a` = `test`.`t1`.`b` and <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t3 on a))))
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq2 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) NO_SEMIJOIN(LOOSESCAN) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) SEMIJOIN(LOOSESCAN) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; Start temporary; End temporary
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated
|
|
Warning 4211 Hint SEMIJOIN(@`subq2` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) SEMIJOIN(@`subq2` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Conflicting hints in same hint comment
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) SEMIJOIN(@subq1 FIRSTMATCH) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq1` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 LOOSESCAN) NO_SEMIJOIN(@subq1 LOOSESCAN) */ *
|
|
FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN(@`subq1` LOOSESCAN) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ NO_SEMIJOIN(@subq1 LOOSESCAN) NO_SEMIJOIN(@subq1 FIRSTMATCH) */ *
|
|
FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY t3 ref a a 4 test.t1.a 1 100.00 Using index; FirstMatch(t1)
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t3)
|
|
Warnings:
|
|
Warning 4211 Hint NO_SEMIJOIN(@`subq1` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ NO_SEMIJOIN(@`subq1` LOOSESCAN) */ `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# Non-supported strategies should give warnings
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq1 INTOEXISTS) NO_SEMIJOIN(@subq2 INTOEXISTS) */ *
|
|
FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 index a a 4 NULL 4 100.00 Using index; LooseScan
|
|
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.a 1 25.00 Using where
|
|
1 PRIMARY t2 ref a a 4 test.t1.b 1 66.67 Using index; FirstMatch(t1)
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near 'INTOEXISTS) NO_SEMIJOIN(@subq2 INTOEXISTS) */ *
|
|
FROM t1
|
|
WHERE t1.a IN (SELECT...' at line 2
|
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join (`test`.`t3`) semi join (`test`.`t2`) where `test`.`t1`.`a` = `test`.`t3`.`a` and `test`.`t2`.`a` = `test`.`t1`.`b`
|
|
# SUBQUERY tests
|
|
# SUBQUERY should disable SEMIJOIN and use specified subquery strategy
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2 WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
EXPLAIN
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 Using where; Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 Using index
|
|
# Query with two subqueries
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq1 INTOEXISTS) SUBQUERY(@subq2 MATERIALIZATION) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
3 MATERIALIZED ty index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq1` INTOEXISTS) SUBQUERY(@`subq2` MATERIALIZATION) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY)))) and <expr_cache><`test`.`t3`.`b`>(<in_optimizer>(`test`.`t3`.`b`,`test`.`t3`.`b` in ( <materialize> (/* select#3 */ select /*+ QB_NAME(`subq2`) */ `test`.`ty`.`a` from `test`.`t1` `ty` ), <primary_index_lookup>(`test`.`t3`.`b` in <temporary table> on distinct_key where `test`.`t3`.`b` = `<subquery3>`.`a`))))
|
|
# Query with nested sub-queries
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq1 INTOEXISTS) SUBQUERY(@subq2 MATERIALIZATION) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 DEPENDENT SUBQUERY tx unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where
|
|
3 MATERIALIZED ty index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq2` MATERIALIZATION) SUBQUERY(@`subq1` INTOEXISTS) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t3`.`a`) in t1 on PRIMARY where <in_optimizer>(`test`.`tx`.`b`,`test`.`tx`.`b` in ( <materialize> (/* select#3 */ select /*+ QB_NAME(`subq2`) */ `test`.`ty`.`a` from `test`.`t1` `ty` ), <primary_index_lookup>(`test`.`tx`.`b` in <temporary table> on distinct_key where `test`.`tx`.`b` = `<subquery3>`.`a`))) and <cache>(`test`.`t3`.`a`) = `test`.`tx`.`a`))))
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION) SUBQUERY(@subq2 INTOEXISTS) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx
|
|
WHERE tx.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty));
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
2 MATERIALIZED tx ALL NULL NULL NULL NULL 4 100.00 Using where
|
|
3 DEPENDENT SUBQUERY ty unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq2` INTOEXISTS) SUBQUERY(@`subq1` MATERIALIZATION) */ `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,`test`.`t3`.`a` in ( <materialize> (/* select#2 */ select /*+ QB_NAME(`subq1`) */ `test`.`tx`.`a` from `test`.`t1` `tx` where <expr_cache><`test`.`tx`.`b`>(<in_optimizer>(`test`.`tx`.`b`,<exists>(<primary_index_lookup>(<cache>(`test`.`tx`.`b`) in t1 on PRIMARY)))) ), <primary_index_lookup>(`test`.`t3`.`a` in <temporary table> on distinct_key where `test`.`t3`.`a` = `<subquery2>`.`a`))))
|
|
# This query does not support SEMIJOIN. Materialization is default
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 4 100.00
|
|
1 PRIMARY t2 ref a a 4 <subquery2>.min(a) 1 100.00 Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t2` where `test`.`t2`.`a` = `<subquery2>`.`min(a)`
|
|
# Use In-to-exists instead
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having <cache>(`test`.`t2`.`a`) = <ref_null_helper>(min(`test`.`t1`.`a`)))))
|
|
# For this query In-to-exists is default
|
|
EXPLAIN EXTENDED
|
|
SELECT a, a IN (SELECT a FROM t1) FROM t2;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY)))) AS `a IN (SELECT a FROM t1)` from `test`.`t2`
|
|
# Force Subquery Materialization
|
|
EXPLAIN EXTENDED
|
|
SELECT a, a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1) FROM t2;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` MATERIALIZATION) */ `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`a`)))) AS `a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) */ a FROM t1)` from `test`.`t2`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ a,
|
|
a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1) FROM t2;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`a`)))) AS `a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1)` from `test`.`t2`
|
|
# This query does not support Subquery Materialization due to type mismatch
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ sum(b) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 1 100.00
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq`) */ sum(`test`.`t1`.`b`) from `test`.`t1` group by `test`.`t1`.`a` having <cache>(`test`.`t2`.`a`) = <ref_null_helper>(sum(`test`.`t1`.`b`)))))
|
|
# Trying to force Subquery Materialization will not change anything
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ sum(b) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 1 100.00
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq`) */ sum(`test`.`t1`.`b`) from `test`.`t1` group by `test`.`t1`.`a` having <cache>(`test`.`t2`.`a`) = <ref_null_helper>(sum(`test`.`t1`.`b`)))))
|
|
# Test hints with prepared statements
|
|
PREPARE stmt1 FROM "EXPLAIN
|
|
SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION)
|
|
SUBQUERY(@subq2 INTOEXISTS) */ * FROM t1
|
|
WHERE t1.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t3)
|
|
AND t1.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t2)";
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
3 DEPENDENT SUBQUERY t2 index_subquery a a 4 func 1 Using index
|
|
2 MATERIALIZED t3 index NULL a 4 NULL 4 Using index
|
|
EXECUTE stmt1;
|
|
id select_type table type possible_keys key key_len ref rows Extra
|
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
|
|
3 DEPENDENT SUBQUERY t2 index_subquery a a 4 func 1 Using index
|
|
2 MATERIALIZED t3 index NULL a 4 NULL 4 Using index
|
|
DEALLOCATE PREPARE stmt1;
|
|
# Test optimizer_switch settings with SUBQUERY hint
|
|
SET optimizer_switch='materialization=off';
|
|
This query will now use In-to-exist
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` having <cache>(`test`.`t2`.`a`) = <ref_null_helper>(min(`test`.`t1`.`a`)))))
|
|
# Force it to use Materialization
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) */ min(a) FROM t1 group by a);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ min(`test`.`t1`.`a`) from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`min(a)`))))
|
|
SET optimizer_switch='materialization=on';
|
|
# This query will now use In-to_exists
|
|
EXPLAIN EXTENDED
|
|
SELECT a, a IN (SELECT a FROM t1) FROM t2;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY)))) AS `a IN (SELECT a FROM t1)` from `test`.`t2`
|
|
Force Materialization
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ a,
|
|
a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1) FROM t2;
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`a`)))) AS `a IN (SELECT /*+ QB_NAME(subq) */ a FROM t1)` from `test`.`t2`
|
|
# Specifying both strategies should give a warning
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq1 MATERIALIZATION, INTOEXISTS)
|
|
SUBQUERY(@subq2 MATERIALIZATION, INTOEXISTS) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near ', INTOEXISTS)
|
|
SUBQUERY(@subq2 MATERIALIZATION, INTOEXISTS) */ *
|
|
FROM t3
|
|
WHERE...' at line 2
|
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and `test`.`ty`.`a` = `test`.`t3`.`b`
|
|
# Non-supported strategies should give warnings
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq1 FIRSTMATCH) SUBQUERY(@subq2 LOOSESCAN) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+ QB_NAME(subq1) */ a FROM t1 tx)
|
|
AND t3.b IN (SELECT /*+ QB_NAME(subq2) */ a FROM t1 ty);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t3 ALL a NULL NULL NULL 4 100.00 Using where
|
|
1 PRIMARY tx eq_ref PRIMARY PRIMARY 4 test.t3.a 1 100.00 Using index
|
|
1 PRIMARY ty eq_ref PRIMARY PRIMARY 4 test.t3.b 1 100.00 Using index
|
|
Warnings:
|
|
Warning 1064 Optimizer hint syntax error near 'FIRSTMATCH) SUBQUERY(@subq2 LOOSESCAN) */ *
|
|
FROM t3
|
|
WHERE t3.a IN (SELECT /*+...' at line 2
|
|
Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` `ty` join `test`.`t1` `tx` join `test`.`t3` where `test`.`tx`.`a` = `test`.`t3`.`a` and `test`.`ty`.`a` = `test`.`t3`.`b`
|
|
SET optimizer_switch= default;
|
|
# Specifying two SUBQUERY for same query block gives warning
|
|
# First has effect, second is ignored
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ SUBQUERY(MATERIALIZATION) SUBQUERY(INTOEXISTS) */ a
|
|
FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`a`))))
|
|
# Try opposite order
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) SUBQUERY(MATERIALIZATION) */ a
|
|
FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Specify at different levels, hint inside block has effect
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(INTOEXISTS) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(@`subq` MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Specify at different levels, opposite order
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(MATERIALIZATION) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(@`subq` INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` MATERIALIZATION) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,`test`.`t2`.`a` in ( <materialize> (/* select#2 */ select /*+ QB_NAME(`subq`) */ `test`.`t1`.`a` from `test`.`t1` ), <primary_index_lookup>(`test`.`t2`.`a` in <temporary table> on distinct_key where `test`.`t2`.`a` = `<subquery2>`.`a`))))
|
|
# Specifying combinations of SUBQUERY and SEMIJOIN/NO_SEMIJOIN
|
|
# for same query block gives warning
|
|
# First has effect, second is ignored
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ SUBQUERY(INTOEXISTS) SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN() is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`select#2` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Try opposite order
|
|
EXPLAIN EXTENDED
|
|
SELECT * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ NO_SEMIJOIN() SUBQUERY(MATERIALIZATION) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`select#2`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
# Specify at different levels, hint inside block has effect
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq MATERIALIZATION) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
|
|
1 PRIMARY t2 ref a a 4 test.t1.a 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(@`subq` MATERIALIZATION) is ignored as conflicting/duplicated
|
|
Note 1003 select /*+ SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a`
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SUBQUERY(@subq INTOEXISTS) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) NO_SEMIJOIN() */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SUBQUERY(@`subq` INTOEXISTS) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ NO_SEMIJOIN(@`subq`) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
EXPLAIN EXTENDED
|
|
SELECT /*+ SEMIJOIN(@subq FIRSTMATCH) */ * FROM t2
|
|
WHERE t2.a IN (SELECT /*+ QB_NAME(subq) SUBQUERY(@subq INTOEXISTS) */ a FROM t1);
|
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
|
1 PRIMARY t2 index NULL a 4 NULL 6 100.00 Using where; Using index
|
|
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
|
|
Warnings:
|
|
Warning 4211 Hint SEMIJOIN(@`subq` FIRSTMATCH) is ignored as conflicting/duplicated
|
|
Note 1003 /* select#1 */ select /*+ SUBQUERY(@`subq` INTOEXISTS) */ `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
|
|
DROP TABLE t1,t2,t3;
|