Image you have a table, and you need to optimize the following query:
SELECT * FROM my_table WHERE a >= 1 AND b = 1 AND c = 1;
At first glance, you might think adding a multi-field index like INDEX(a, b, c) will solve the problem. But is that really the best choice?
A multi-field index (also called a composite index) is an index that covers more than one column. For example:
CREATE INDEX index_abc ON my_table (a, b, c);
This means the table is sorted in lexicographical order by:
a first.b within rows where a is the same.c within rows where both a and b are the same.But how does the order of column in an index affect performance in range query like a >= 1 ?
Let’s compare two different multi-field indexes:
INDEX(a, b, c)
INDEX(b, c, a)
And we will analyze their performance on this query:
SELECT * FROM my_table WHERE a >= 1 AND b = 1 AND c = 1;
With INDEX(a, b, c), the query looks like this:
SELECT * FROM my_table WHERE a >= 1 AND b = 1 AND c = 1;
Here’s how MySQL processes it:
a >= 1;a is a range condition, the database cannot use the remaining columns (b and c) efficiently. The sorting order for b and c is broken after the range condition on a.a >= 1 range to find rows that match b = 1 and c = 1.Now let’s change the index to INDEX(b, c, a) and adjust the query accordingly:
SELECT * FROM my_table WHERE b = 1 AND c = 1 AND a >= 1;
Here’s how MySQL processes it:
b = 1.c = 1.a.Because b and c are exact mathces, the database could efficiently use the index for both columns before applying the range condition on a.
= should come first in the index.>=, >, <, etc., should be placed last in the index.