I'm currently checking the slow_query_log with log_queries_not_using indexes enabled of a mysql instance. There is one query that shows up very frequently, it is not a slow query, but a query that doesn't use indexes.
The query has the following structure:
select ...
from `Tb1`
left join `Tb2` on `Tb1`.`id` = `Tb2`.`id_tb1`
left join `Tb3` on `Tb2`.`id_common` = `Tb3`.`id_common`
left join `Tb4` on `Tb2`.`id` = `Tb4`.`id_tb2`
left join `Tb5` on `Tb1`.`id_tb5` = `Tb5`.`id`;
The Explain for this query is the following:
+----+-------------+--------+------------+--------+-----------------+------------------+---------+-----------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+--------+-----------------+------------------+---------+-----------------------+------+----------+-------------+
| 1 | SIMPLE | Tb1 | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb2 | NULL | ref | fk_tb2_tb1_idx | fk_tb2_tb1_idx | 4 | schema.tb1.id | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb3 | NULL | ref | fk_tb2_tb3_idx | fk_tb2_tb3_idx | 4 | schema.Tb2.id_common | 1 | 100.00 | Using index |
| 1 | SIMPLE | Tb4 | NULL | ref | fk_tb4_tb2_idx | fk_tb4_tb2_idx | 4 | schema.Tb2.id | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb5 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | schema.tb1.id_tb5 | 1 | 100.00 | NULL |
+----+-------------+--------+------------+--------+-----------------+------------------+---------+-----------------------+------+----------+-------------+
As we can see from the output of the explain, the query does not use any index on Tb1 even though it has indexes on the columns on which are joined with other tables.
QUESTION 1:
Why this query does not uses the index on Tb1 table?
Then, i tried using an "order by" using the id of Tb1 like this:
select ...
from `Tb1`
left join `Tb2` on `Tb1`.`id` = `Tb2`.`id_tb1`
left join `Tb3` on `Tb2`.`id_common` = `Tb3`.`id_common`
left join `Tb4` on `Tb2`.`id` = `Tb4`.`id_tb2`
left join `Tb5` on `Tb1`.`id_tb5` = `Tb5`.`id`
order by Tb1.id;
Getting the following result in the explain:
+----+-------------+--------+------------+--------+-----------------+-------------------+---------+----------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+--------+-----------------+-------------------+---------+----------------------+------+----------+-------------+
| 1 | SIMPLE | Tb1 | NULL | index | NULL | PRIMARY | 4 | NULL | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb2 | NULL | ref | fk_tb2_tb1_idx | fk_tb2_tb1_idx | 4 | schema.tb1.id | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb3 | NULL | ref | fk_tb2_tb3_idx | fk_tb2_tb3_idx | 4 | schema.Tb2.id_common | 1 | 100.00 | Using index |
| 1 | SIMPLE | Tb4 | NULL | ref | fk_tb4_tb2_idx | fk_tb4_tb2_idx | 4 | schema.Tb2.id | 1 | 100.00 | NULL |
| 1 | SIMPLE | Tb5 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | schema.tb1.id_tb5 | 1 | 100.00 | NULL |
+----+-------------+--------+------------+--------+-----------------+-------------------+---------+----------------------+------+----------+-------------+
As we can see from the output of explain no. 2, it now uses the primay key as index.
QUESTION 2:
Using this order by: a) Will improve the performance of the query? b) The query performance would be the same. c) Will degrade the performance of the query?
EXPLAIN
when you have only one row in a table, or even 10 rows. – Rick James Apr 30 '17 at 0:34