I answered nearly the same question here: Does Order of Fields of Multi-Column Index in MySQL Matter
Yes, the order of columns does matter. To choose the right order of columns, you should have a specific query in mind. You haven't shown a query yet in this question.
If your query conditions are all =
comparisons then the order of columns does not matter much. Some people try to micro-optimize by putting more selective columns to the left, but I find this does not make a significant difference.
For example, if you are looking up someone in the phone book by their full name, do you really care if the book is sorted by last name first or first name first? You're going to filter on both fields anyway.
But if you have a mix of =
comparisons and other types of comparison operators, then the column order really does matter.
Basically, you can have as many =
terms as you want, and the columns for these comparisons must be on the left end of the list of columns in the index. Then you can have ONE column in the index for an inequality comparison. Any further columns you search will not use the index.
You mentioned in a comment that you have a query with 3 comparisons with <
. Like this:
... WHERE a < 1 AND b < 2 AND c < 3
This can use an index on at most one of these columns. In this case, you should choose the condition that will be most selective, i.e. that will match the smallest subset of rows.
If the terms used =
:
... WHERE a = 1 AND b = 2 AND c = 3
Then all columns of a multi-column index on (a, b, c)
could help the search, and the order of columns would not matter.
If you had a mix of comparisons:
... WHERE a = 1 AND b < 2 AND c < 3
Then you may have an index with a
as the leftmost column, and one of b
or c
following it. But if you had both b
and c
, still only one would be used for the search — the first one that follows a
.
See my presentation How to Design Indexes, Really or the video.
Re your updated question with an example query:
select * from pic_tag_relations where tag_id in ($all_tag_ids) && contrast_score>2.5 && quality_score>3 && is_okay=1 && pic_ratio_type='2' && already_used_count<10
You could have an index with (is_okay, pic_ratio_type)
as the first columns, then you get to choose which one of the other columns should be the third column. The other columns are referenced in terms that use some comparison operator other than =
. Which column is best would be based on how well each condition is likely to select a smaller subset of rows.
The other terms will also filter out rows, but not by using the index. They'll have to compare to the rows one by one as they are returned by the indexed search.