简体   繁体   English

Mysql 5.6优化器不使用小表连接中的索引

[英]Mysql 5.6 optimizer doesn't use indexes in small tables joins

We have two tables - the first is relatively big (contact table) 250k rows and the second is small(user table, < 10 rows). 我们有两个表 - 第一个是相对较大的(联系表)250k行,第二个是小表(用户表,<10行)。 On mysql 5.6 version I have next explain result: 在mysql 5.6版本上我有下一个解释结果:

EXPLAIN SELECT  
  o0_.id AS id_0,  
  o8_.first_name, 
  o8_.last_name 
FROM  
  contact o0_  
  LEFT JOIN user o8_ ON o0_.user_owner_id = o8_.id  
LIMIT  
  25 OFFSET 100

+----+-------------+-------+-------+---------------+----------------------+---------+------+--------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key                  | key_len | ref  | rows   | Extra                                              |
+----+-------------+-------+-------+---------------+----------------------+---------+------+--------+----------------------------------------------------+
|  1 | SIMPLE      | o0_   | index | NULL          | IDX_403263ED9EB185F9 | 5       | NULL | 253030 | Using index                                        |
|  1 | SIMPLE      | o8_   | ALL   | PRIMARY       | NULL                 | NULL    | NULL |      5 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+----------------------+---------+------+--------+----------------------------------------------------+

2 rows in set (0,00 sec) 2行(0,00秒)

When i use force index for join: 当我使用force index进行连接时:

EXPLAIN SELECT  
  o0_.id AS id_0,  
  o8_.first_name, 
  o8_.last_name 
FROM  
  contact o0_  
  LEFT JOIN user o8_ force index for join(`PRIMARY`) ON o0_.user_owner_id = o8_.id  
LIMIT  
  25 OFFSET 100

or adding indexes on fields which appears in select clause (first_name, last_name) on user table: 或在用户表上的select子句(first_name,last_name)中显示的字段上添加索引:

alter table user add index(first_name, last_name);

Explain result changes to this: 解释结果更改为:

    +----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
| id | select_type | table | type   | possible_keys | key                  | key_len | ref                     | rows   | Extra       |
+----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
|  1 | SIMPLE      | o0_   | index  | NULL          | IDX_403263ED9EB185F9 | 5       | NULL                    | 253030 | Using index |
|  1 | SIMPLE      | o8_   | eq_ref | PRIMARY       | PRIMARY              | 4       | o0_.user_owner_id |      1 | NULL        |
+----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
    2 rows in set (0,00 sec)

On mysql 5.5 version I have same explain result without additional indexes: 在mysql 5.5版本上,我有相同的解释结果,没有附加索引:

    +----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
| id | select_type | table | type   | possible_keys | key                  | key_len | ref                     | rows   | Extra       |
+----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
|  1 | SIMPLE      | o0_   | index  | NULL          | IDX_403263ED9EB185F9 | 5       | NULL                    | 255706 | Using index |
|  1 | SIMPLE      | o8_   | eq_ref | PRIMARY       | PRIMARY              | 4       | o0_.user_owner_id |      1 |             |
+----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
2 rows in set (0.00 sec)

Why i need force use PRIMARY index or add extra indexes on mysql 5.6 version? 为什么我需要强制使用PRIMARY索引或在mysql 5.6版本上添加额外的索引? Same behavior occurs with other selects, when join small tables. 当连接小表时,其他选择会发生相同的行为。

If you have a table with so few rows, it may actually be faster to do a full table scan, than going to an index, locate the records and then go back to the table. 如果你有一个行数这么少的表,那么进行全表扫描实际上要比转到索引更快,找到记录然后再回到表中。 If you have other fields in the user table apart from the 3 in the query, then you may consider adding a covering index, but franly, I do not think that any of this would have significant affect on the speed of the query. 如果除了查询中的3之外,用户表中还有其他字段,那么您可以考虑添加覆盖索引,但坦率地说,我认为这不会对查询的速度产生重大影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM