mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Derived tables and union can now create distinct keys
The idea is that instead of marking all select_lex's with DISTINCT, we only mark those that really need distinct result. Benefits of this change: - Temporary tables used with derived tables, UNION, IN are now smaller as duplicates are removed already on the insert phase. - The optimizer can now produce better plans with EQ_REF. This can be seen from the tests where several queries does not anymore materialize derived tables twice. - Queries affected by 'in_predicate_conversion_threshold' where large IN lists are converted to sub query produces better plans. Other things: - Removed on duplicate call to sel->init_select() in LEX::add_primary_to_query_expression_body() - I moved the testing of tab->table->pos_in_table_list->is_materialized_derived() in join_read_const_table() to the caller as it caused problems for derived tables that could be proven to be const tables. This also is likely to fix some bugs as if join_read_const_table() was aborted, the table was left marked as JT_CONST, which cannot be good. I added an ASSERT there for now that can be removed when the code has been properly tested.
This commit is contained in:
@ -743,21 +743,19 @@ a b
|
||||
explain extended select * from t1
|
||||
where a in (values (1));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
1 PRIMARY <derived2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1)) `tvc_0`) where 1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a`
|
||||
explain extended select * from t1
|
||||
where a in (select * from (values (1)) as tvc_0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
1 PRIMARY <derived3> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1)) `tvc_0`) where 1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a`
|
||||
# IN-subquery with VALUES structure(s) : UNION with VALUES on the first place
|
||||
select * from t1
|
||||
where a in (values (1) union select 2);
|
||||
@ -776,7 +774,7 @@ explain extended select * from t1
|
||||
where a in (values (1) union select 2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT SUBQUERY <derived2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
@ -787,7 +785,7 @@ where a in (select * from (values (1)) as tvc_0 union
|
||||
select 2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00
|
||||
2 DEPENDENT SUBQUERY <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL
|
||||
@ -812,7 +810,7 @@ where a in (select 2 union values (1));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT UNION <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
@ -848,7 +846,7 @@ explain extended select * from t1
|
||||
where a in (values (1) union all select b from t1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT SUBQUERY <derived2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
Warnings:
|
||||
@ -858,7 +856,7 @@ where a in (select * from (values (1)) as tvc_0 union all
|
||||
select b from t1);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00
|
||||
2 DEPENDENT SUBQUERY <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
Warnings:
|
||||
@ -880,18 +878,18 @@ explain extended select * from t1
|
||||
where a not in (values (1),(2));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||
3 DEPENDENT SUBQUERY <derived2> unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#3 */ select `tvc_0`.`1` from (values (1),(2)) `tvc_0` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery3>`.`1`))))
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a`) in <temporary table> on distinct_key where trigcond(<cache>(`test`.`t1`.`a`) = `tvc_0`.`1`)))))
|
||||
explain extended select * from t1
|
||||
where a not in (select * from (values (1),(2)) as tvc_0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
|
||||
2 DEPENDENT SUBQUERY <derived3> unique_subquery distinct_key distinct_key 4 func 1 100.00 Using where; Full scan on NULL key
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (/* select#2 */ select `tvc_0`.`1` from (values (1),(2)) `tvc_0` ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where `test`.`t1`.`a` = `<subquery2>`.`1`))))
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where !<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a`) in <temporary table> on distinct_key where trigcond(<cache>(`test`.`t1`.`a`) = `tvc_0`.`1`)))))
|
||||
# NOT IN subquery with VALUES structure(s) : UNION with VALUES on the first place
|
||||
select * from t1
|
||||
where a not in (values (1) union select 2);
|
||||
@ -978,21 +976,19 @@ a b
|
||||
explain extended select * from t1
|
||||
where a = any (values (1),(2));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00
|
||||
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 MATERIALIZED <derived2> ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
1 PRIMARY <derived2> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a`
|
||||
explain extended select * from t1
|
||||
where a = any (select * from (values (1),(2)) as tvc_0);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00
|
||||
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 MATERIALIZED <derived3> ALL NULL NULL NULL NULL 2 100.00
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
1 PRIMARY <derived3> eq_ref distinct_key distinct_key 4 test.t1.a 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
Warnings:
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` semi join ((values (1),(2)) `tvc_0`) where 1
|
||||
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from (values (1),(2)) `tvc_0` join `test`.`t1` where `tvc_0`.`1` = `test`.`t1`.`a`
|
||||
# ANY-subquery with VALUES structure(s) : UNION with VALUES on the first place
|
||||
select * from t1
|
||||
where a = any (values (1) union select 2);
|
||||
@ -1011,7 +1007,7 @@ explain extended select * from t1
|
||||
where a = any (values (1) union select 2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT SUBQUERY <derived2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union4,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
@ -1022,7 +1018,7 @@ where a = any (select * from (values (1)) as tvc_0 union
|
||||
select 2);
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY <derived3> ref key0 key0 4 func 2 100.00
|
||||
2 DEPENDENT SUBQUERY <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL
|
||||
@ -1047,7 +1043,7 @@ where a = any (select 2 union values (1));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT UNION <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
@ -1140,7 +1136,7 @@ where a = any (select 1 union values (1));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 6 100.00 Using where
|
||||
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
4 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT UNION <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union2,4> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
@ -2688,9 +2684,9 @@ a
|
||||
explain extended select a from t1 where a in (values (7) union values (8));
|
||||
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
|
||||
4 DEPENDENT SUBQUERY <derived2> ref key0 key0 4 func 2 100.00
|
||||
4 DEPENDENT SUBQUERY <derived2> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
5 DEPENDENT UNION <derived3> ref key0 key0 4 func 2 100.00
|
||||
5 DEPENDENT UNION <derived3> eq_ref distinct_key distinct_key 4 func 1 100.00
|
||||
3 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||
NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL NULL
|
||||
Warnings:
|
||||
@ -2951,6 +2947,8 @@ values ((values (4)), (select 5)), ((select 2), (values (8)));
|
||||
values ((values (1) union values (1)));
|
||||
(values (1) union values (1))
|
||||
1
|
||||
values ((values (1) union all values (1)));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
values ((values (1) union values (1) union values (1)));
|
||||
(values (1) union values (1) union values (1))
|
||||
1
|
||||
|
Reference in New Issue
Block a user