Comment 4 for bug 944706

Revision history for this message
Timour Katchaounov (timour) wrote : Re: Query with impossible HAVING takes 1 millisec on 5.2 and 8 sec on 5.3

Possible solutions:

1) Delayed constant optimization.

There are various optimizations that rely on constant evaluation.
One way to address this problem would be to:
- Decide on which constant optimizations are the most important ones, and
- add an extra phase in the beginning of query execution that repeats
  all important constant optimizations for expensive conditions.
As a result of this phase we may detect at the very start of query execution that
a query result is empty, e.g. because of FALSE WHERE or HAVING clauses.

The disadvantages of this solution are:
- There may be dependencies on other optimizations, which in turn may make the
approach unfeasible for some (or most) of the constant optimizations.
- If not all optimizations are repeated, there will still be cases of performance
regressions compared to other server versions that use subqueries during
constant optimization, and it is hard to know which cases are the most common ones.

2) Constant optimization for "cheap" subqueries

The second approach is to:
- Pre-optimize early those queries that may potentially be used for constant optimization.
- Estimate the cost of subquery evaluation for the above subqueries.
- Modify the Item::is_expensive() method to use the cost estimate to decide if a subquery is "cheap".
- Evaluate "cheap" subqueries whenever necessary. This would follow automatically from the changed
implementation of is_expensive().

Problems/disadvantages:
- There are few cases when EXPLAIN needs data structures (TABLE_LIST) that were changed destructively
while a subquery was executed *before* the actual explain code.
- The most time-consuming part seems to be that enabling constant optimization for subqueries results in
several wrong results. Some of them are known bugs in MySQL, others possibly specific to MariaDB.