I have MySQL version 8.0.37.
From what I understand about a multi-column index in this version, it will be used by MySQL ONLY if the query contains a subset of all the columns, starting from the first.
For ex, I have this index in my InnoDB table
mysql> show indexes from my_table;
+------------------------+------------+------------------------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+------------------------+------------+------------------------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| my_table | 0 | PRIMARY | 1 | id | A | 32643 | NULL | NULL | | BTREE | | | YES | NULL |
| my_table | 1 | my_table_entity_id | 1 | entity_id | A | 20160 | NULL | NULL | | BTREE | | | YES | NULL |
| my_table | 1 | my_table_entity_id_sub_id_value | 1 | entity_id | A | 18222 | NULL | NULL | | BTREE | | | YES | NULL |
| my_table | 1 | my_table_entity_id_sub_id_value | 2 | sub_id | A | 32985 | NULL | NULL | | BTREE | | | YES | NULL |
| my_table | 1 | my_table_entity_id_sub_id_value | 3 | value | A | 32545 | NULL | NULL | | BTREE | | | YES | NULL |
+------------------------+------------+------------------------------------------------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
With my_table_entity_id_sub_id_value
index, I can run queries over entity_id
, or both entity_id
and sub_id
or all the 3 columns. This is also what the MySQL documentation says.
However, this is the explain analyze
output of a query over only the 2nd and 3rd columns, i.e., sub_id
and value
, and still the index is being used.
mysql> explain analyze select distinct entity_id from my_table where sub_id = 107 and value = 'd90e7a26-2fc5-4e16-87c5-a2e9da5a26f7';
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| EXPLAIN |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| -> Group (no aggregates) (cost=3552 rows=330) (actual time=3.52..14.7 rows=3103 loops=1)
-> Filter: ((my_table.`value` = 'd90e7a26-2fc5-4e16-87c5-a2e9da5a26f7') and (my_table.sub_id = 107)) (cost=3519 rows=330) (actual time=3.44..14.3 rows=3103 loops=1)
-> Covering index scan on my_table using my_table_entity_id_sub_id_value (cost=3519 rows=32985) (actual time=0.0741..10.4 rows=33202 loops=1)
|
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.39 sec)
I realise it's a "covering index" scan. What I understand about them is that they're used for retrieving values directly from the index, so I understand entity_id
which I'm select
ing is in that index. However, the where
is still over only the 2nd and 3rd columns, and that is the filtration criteria.
Am I missing something here? What am I not understanding about covering index scans?