[MDEV-2372] LP:944706 - Query with impossible or constant subquery in WHERE or HAVING is not precomputed and thus not part of optimization Created: 2012-03-02 Updated: 2014-06-20 Resolved: 2012-10-04 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor |
| Reporter: | Elena Stepanova | Assignee: | Timour Katchaounov (Inactive) |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | Launchpad | ||
| Attachments: |
|
| Description |
|
The following query SELECT MAX( alias2.a ) AS field works almost instantly on MariaDB 5.2, but takes quite long, depending on the amount of data in t1, on MariaDB 5.3. bzr version-info bzr version-info EXPLAIN in 5.3: id select_type table type possible_keys key key_len ref rows filtered Extra optimizer_switch in 5.3 (default): EXPLAIN in 5.2: id select_type table type possible_keys key key_len ref rows filtered Extra optimizer_switch in 5.2 (default): Test case: CREATE TABLE t1 ( a VARCHAR(16), KEY (a) );
|
| Comments |
| Comment by Sergei Petrunia [ 2012-03-02 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3 This bug demonstrates a problem with the optimizer, in particular with the choice between IN->EXISTS and Materialization strategies. We have a query: const1 IN (SELECT inner_expr FROM ... ) Why would the optimizer pick Materialization, when we have "const1" on the left side, and so will make only one lookup in the materialized table? It is obvious that IN->EXISTS will always be better than Materialization for such cases. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3 The real reason for the difference in execution times between 5.2 and 5.3 is a result of re-engineering subquery optimization to be done during the optimization phase. One consequence of this change is that subqueries can no longer be executed during optimization of the outer query. The reason for this is two-fold: (1) A subquery may be arbitrarily expensive, thus it may make optimization and explain arbitrarily slow. In 5.2 a subquery of the type "const1 IN (SELECT inner_expr FROM ... )" is evaluated during the optimize_cond phase in JOIN::optimize, the result is substituted in the containing condition, and the condition is simplified. In the case of this example, the optimizer finds that the HAVING clause is FALSE, and produces an empty result without even executing the query. In 5.3 subquery predicates are not evaluated during optimization, therefore such subsitution cannot be performed, and the query is executed as a normal JOIN. Further investigation of the query plan in 5.3 shows that if we use the default join_cache_level=2, execution is very slow ~1.8 sec, while with join_cache_level=0, execution takes ~0.07 sec. This problem can be shown without a subquery, thus it is not related to this bug. The attachment below contains detailed EXPLAINs, and execution times for 5.2/5.3 with various combinaitons of materialization=on/off, and join_cache_level=0/2. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
EXPLAINs, and execution times for 5.2, 5.3 with different join_cache_level, and materialization. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-20 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3 1) Delayed constant optimization. There are various optimizations that rely on constant evaluation.
The disadvantages of this solution are:
2) Constant optimization for "cheap" subqueries The second approach is to:
Problems/disadvantages:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-21 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3
If subqueries are expensive (5.3), the query is processed as follows:
Since the subquery is evaluated only once, one may wonder why this query
---
--- This plan takes 1.8 sec. With join_cache_level=0 there is a much better plan:
---
--- This plan takes 0.07 sec. If we allow subqueries to be used for constant optimization we mask the problem | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-03-21 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3 SELECT MAX(alias2.a) If subqueries are not expensive (5.2, or changed 5.3) the query is optimized as the This allows the JOIN optimizer to find a good plan that takes 0.02 sec:
---
--- In 5.3 where subqueries are expensive, the IN cannot be optimized away, and the OR condition doesn't allow a plan with ref access. The resulting plan takes ~ 3 sec: ---
---
--- Since there is subquery caching, the subquery itself is executed only once, but the function Finally, as in the original query the above plan can be improved by setting join_cache_level=0 down to 0.07 sec: ---
---
--- | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2012-03-21 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible or constant subquery in WHERE or HAVING is not precomputed and thus not part of optimization | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Timour Katchaounov (Inactive) [ 2012-06-19 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Re: Query with impossible or constant subquery in WHERE or HAVING is not precomputed and thus not part of optimization | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Rasmus Johansson (Inactive) [ 2012-06-19 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Launchpad bug id: 944706 |