2016-03-09 29 views
3

我們有兩個表 - 第一個是比較大的(聯繫表)250k行,第二個是小的(用戶表,< 10行)。在MySQL 5.6版本我已經解釋下的結果:在集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秒)

當我使用力指數爲加入:上

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) 

爲什麼需要強制使用主索引或在MySQL 5.6版本添加額外的索引? 當連接小表時,與其他選擇相同的行爲。

回答

1

如果您有一個行數很少的表,那麼執行全表掃描的速度可能會快於查找索引,找到記錄然後返回表格。如果用戶表中的其他字段除了查詢中的3以外,那麼您可以考慮添加一個覆蓋索引,但是很顯然,我不認爲這會對查詢速度產生重大影響。

+0

問題是這些連接對全表掃描的性能影響是顯着的: 0.04秒,索引與3.61秒全表掃描 – Max

+0

然後保持索引提示。 – Shadow