繁体   English   中英

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

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

我们有两个表 - 第一个是相对较大的(联系表)250k行,第二个是小表(用户表,<10行)。 在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行(0,00秒)

当我使用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

或在用户表上的select子句(first_name,last_name)中显示的字段上添加索引:

alter table user add index(first_name, last_name);

解释结果更改为:

    +----+-------------+-------+--------+---------------+----------------------+---------+-------------------------+--------+-------------+
| 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)

在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)

为什么我需要强制使用PRIMARY索引或在mysql 5.6版本上添加额外的索引? 当连接小表时,其他选择会发生相同的行为。

如果你有一个行数这么少的表,那么进行全表扫描实际上要比转到索引更快,找到记录然后再回到表中。 如果除了查询中的3之外,用户表中还有其他字段,那么您可以考虑添加覆盖索引,但坦率地说,我认为这不会对查询的速度产生重大影响。

暂无
暂无

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

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