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.