diff options
author | unknown <timour@askmonty.org> | 2012-05-30 00:18:53 +0300 |
---|---|---|
committer | unknown <timour@askmonty.org> | 2012-05-30 00:18:53 +0300 |
commit | 941018f8d10240e9ec457ea6ab984844c343f6b6 (patch) | |
tree | bd039c38d5d6cfa577e5f6dd53442371e4f3acf5 /mysql-test/r/join_outer.result | |
parent | 4fa89b5fe05280fefa2b30df927d0db6c6888f98 (diff) | |
download | mariadb-git-941018f8d10240e9ec457ea6ab984844c343f6b6.tar.gz |
Patch for mdev-287: CHEAP SQ: A query with subquery in SELECT list, EXISTS, inner joins takes hundreds times longer
Analysis:
The fix for lp:944706 introduces early subquery optimization.
While a subquery is being optimized some of its predicates may be
removed. In the test case, the EXISTS subquery is constant, and is
evaluated to TRUE. As a result the whole OR is TRUE, and thus the
correlated condition "b = alias1.b" is optimized away. The subquery
becomes non-correlated.
The subquery cache is designed to work only for correlated subqueries.
If constant subquery optimization is disallowed, then the constant
subquery is not evaluated, the subquery remains correlated, and its
execution is cached. As a result execution is fast.
However, when the constant subquery was optimized away, it was neither
cached by the subquery cache, nor it was cached by the internal subquery
caching. The latter was due to the fact that the subquery still appeared
as correlated to the subselect_XYZ_engine::exec methods, and they
re-executed the subquery on each call to Item_subselect::exec.
Solution:
The solution is to update the correlated status of the subquery after it has
been optimized. This status consists of:
- st_select_lex::is_correlated
- Item_subselect::is_correlated
- SELECT_LEX::uncacheable
- SELECT_LEX_UNIT::uncacheable
The status is updated by st_select_lex::update_correlated_cache(), and its
caller st_select_lex::optimize_unflattened_subqueries. The solution relies
on the fact that the optimizer already called
st_select_lex::update_used_tables() for each subquery. This allows to
efficiently update the correlated status of each subquery without walking
the whole subquery tree.
Notice that his patch is an improvement over MySQL 5.6 and older, where
subqueries are not pre-optimized, and the above analysis is not possible.
Diffstat (limited to 'mysql-test/r/join_outer.result')
-rw-r--r-- | mysql-test/r/join_outer.result | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 49a6a0d76d3..074b8bcadaa 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1872,7 +1872,7 @@ SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 -2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where +2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where Warnings: Note 1003 select NULL AS `a` from `test`.`t2` where 1 DROP TABLE t1,t2,t3; |