I have the following covering indices:
INDEX (col1, col3); -- index 1
INDEX (col1, col2, col3); -- index 2
because I would like to support the following type of queries:
1)
SELECT col3
FROM my_table
WHERE col1 = ... AND
col2 = ...
ORDER BY col3
2)
SELECT col3
FROM my_table
WHERE col1 = ...
ORDER BY col3
I am unfamiliar with how a covering index works. Is index 1 redundant? Or does a covering index requires that the columns be side by side?
Best Answer
"Covering" is the wrong term to start with. I'll get back to that in a minute.
The optimal index for your queries can be summarized:
=
columns in theWHERE
, in -any_ order.ORDER BY
columns in the same order, and either be allASC
or allDESC
. (MySQL 8.0 has an exception here.)Your index 1 is necessary and sufficient for query 2.
Your index 2 is necessary and sufficient for query 1.
Anything different would be sub-optimal.
Note that they would also be "covering" in that all the columns anywhere in the
SELECT
are found in the respective indexes.Index 2 "covers" both queries, but it is not very good for Query 2.
INDEX(a), INDEX(a,b)
, toss the former.For those tips, plus more, see http://mysql.rjweb.org/doc.php/index_cookbook_mysql
This is "covering", but not efficient because
col99
in first in the index, but not used for filtering or sorting:It might be used, but only because it is covering. It can't be used for filtering or sorting.
This is "covering" and might be used to avoid sorting because the
ORDER BY
column(s) are first:Query 1 would be just as happy with this regardless of the cardinality of the individual columns:
Back to the title question:
Answer:
An analogy
A B+Tree has two important properties: