You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BUG#11752097: SELECT ... WHERE (col1, col2) IN ((const, const))
is optimized, non-SELECT not
SELECT statements go through JOIN::optimize(). UPDATE/DELETE
statements do not call JOIN::optimize(), which means that a lot
of query optimizations available for SELECTs are not available
for these.
However, UPDATE/DELETE makes some attempts to do low-hanging
optimizations, e.g. some condition optimizations and range
optimization. Range access offers pretty good performance
even in cases where a SELECT statement could have done eq-ref.
In the bug, we have:
SELECT * FROM t1 WHERE (c1, c2) IN ((const, const))
DELETE FROM t1 WHERE (c1, c2) IN ((const, const))
UPDATE t1 SET c1=const WHERE (c1, c2) IN ((const, const))
The SELECT uses index lookup using the const values while the
UPDATE/DELETE statements do table scan. Making these use
lookup like the SELECT is an big task. However, if the
queries had used range access the performance would be close
to index lookup.
A predicate of the form "(c1, c2) IN ((const, const))" is
initially created as
Item_func_eq(Item_row(Item_field c1, Item_field c2),
Item_row(const, const))
For SELECT queries, this predicate is transformed into
Item_cond_and(Item_func_eq(Item_field c1, const),
Item_func_eq(Item_field c2, const))
by optimize_cond() before the range optimizer is invoked. The
range optimizer is not prepared to process Item_rows and
simply ignores them. That's why the UPDATE/DELETE statements
do not use the range access method.
The fix is to do some more condition processing for
UPDATE/DELETE so that the Item_rows are transformed into
something the range optimizer can handle.
0 commit comments