diff options
author | unknown <timour@askmonty.org> | 2011-11-21 18:00:55 +0200 |
---|---|---|
committer | unknown <timour@askmonty.org> | 2011-11-21 18:00:55 +0200 |
commit | f8dbbc010f37de4afe74b49037f8c22c4d788550 (patch) | |
tree | fb7336073946901c2fbb4cb33b7106c9278b14b7 /sql/multi_range_read.cc | |
parent | 0693f4d9168eeee399f9d636c9ba81981e484daf (diff) | |
download | mariadb-git-f8dbbc010f37de4afe74b49037f8c22c4d788550.tar.gz |
Fix bug lp:833777
Analysis:
The optimizer distinguishes two kinds of 'constant' conditions:
expensive ones, and non-expensive ones. The non-expensive conditions
are evaluated inside make_join_select(), and if false, already the
optimizer detects empty query results.
In order to avoid arbitrarily expensive optimization, the evaluation of
expensive constant conditions is delayed until execution. These conditions
are attached to JOIN::exec_const_cond and evaluated in the beginning of
JOIN::exec. The relevant execution logic is:
JOIN::exec()
{
if (! join->exec_const_cond->val_int())
{
produce an empty result;
stop execution
}
continue execution
execute the original WHERE clause (that contains exec_const_cond)
...
}
As a result, when an expensive constant condition is
TRUE, it is evaluated twice - once through
JOIN::exec_const_cond, and once through JOIN::cond.
When the expensive constant condition is a subquery,
predicate, the subquery is evaluated twice. If we have
many levels of subqueries, this logic results in a chain
of recursive subquery executions that walk a perfect
binary tree. The result is that for subquries with depth N,
JOIN::exec is executed O(2^N) times.
Solution:
Notice that the second execution of the constant conditions
happens inside do_select(), in the branch:
if (join->table_count == join->const_tables) { ... }
In this case exec_const_cond is equivalent to the whole WHERE
clause, therefore the WHERE clause has already been checked in
the beginnig of JOIN::exec, and has been found to be true.
The bug is addressed by not evaluating the WHERE clause if there
was exec_const_conds, and it was TRUE.
Diffstat (limited to 'sql/multi_range_read.cc')
0 files changed, 0 insertions, 0 deletions