Question

I have the following query:

select * from my_table 
where (col1, col2) in ( (1000,1), (2000,2) )

I have indexes defined on col1, col2 and col1 and col2 together. If I run an explain on it, I see that mysql does not find an available index to use. Interestingly enough if I put only one pair in the IN clause, the explain finds all the indexes.

Tried force index, does not help

Any ideas, how can I make mysql recognize the index?

Was it helpful?

Solution 2

I managed to solve this without upgrading the mysql version, by adding an extra where in condition on one of the columns only:

select * from my_table 
where (col1, col2) in ( (1000,1), (2000,2) )
and col1 in (1000,2000)

This way, the optimizer will find the index on col1, and will search by it, which did the job for me.

OTHER TIPS

You need MySql version 5.7.3 or above
Earlier versions do not implement an optimization for row constructor expressions

Please follow this link for details: https://dev.mysql.com/doc/refman/5.7/en/range-optimization.html#row-constructor-range-optimization

8.2.1.3.4 Range Optimization of Row Constructor Expressions

As of MySQL 5.7.3, the optimizer is able to apply the range scan access method to queries of this form:

SELECT ... FROM t1 WHERE ( col_1, col_2 ) IN (( 'a', 'b' ), ( 'c', 'd' ));

Previously, for range scans to be used it was necessary for the query to be written as:

SELECT ... FROM t1 WHERE ( col_1 = 'a' AND col_2 = 'b' ) OR ( col_1 = 'c' AND col_2 = 'd' );

Note: a row constructor is an expression of a form:
( value1, value2, ... ,valueN) or ROW( val1, val2, ..., valN).

I wasn't not aware about this; so tried out first (Fiddle http://sqlfiddle.com/#!2/f88bb/2) and yes it's correct; for a multi column IN clause it's using full table scan instead of using the index available.

After some more search found that it's a BUG in MySQL which is targeted to be released or fixed in MySQL 6.x.

See here for a full info Multi column IN does not use index

So for now you can transform your query to use single IN clause so that it recognizes the index; like

select * from my_table 
where col1 in ( 1000,2000) and col2 in (1,2)

Person who created the BUG/Optimization request has explained (OR) given reproduction steps here

Multi-Column IN clause – Unexpected MySQL Issue

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top