for i in `seq 1 1000` ; do mysql -uroot test -e 'insert into department values (27760,repeat(char(65+rand()*58),rand()*20))';
done
explain
select *
from
employee as A,department as B
where
A.LastName = 'zhou'
and B.DepartmentID = A.DepartmentID
and B.DepartmentName = 'TBX';
+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+
| 1 | SIMPLE | A | ref | IND_L_D,IND_DID | IND_L_D | 43 | const | 1 | Using where |
| 1 | SIMPLE | B | ref | IND_D,IND_DN | IND_D | 5 | test.A.DepartmentID | 1 | Using where |
+----+-------------+-------+------+-----------------+---------+---------+---------------------+------+-------------+
可以看到這里,MySQL執行計劃對表department使用了索引IND_D,那么A表命中一條記錄為(zhou,27760);根據B.DepartmentID=27760將返回1010條記錄,然后根據條件DepartmentName = 'TBX'進行過濾。
這里可以看到如果B表選擇索引IND_DN,效果要更好,因為DepartmentName = 'TBX'僅僅返回10條記錄,再根據條件A.DepartmentID=B.DepartmentID過濾之。
這個案例中因為數據量很小,性能還相差不大,但如果生產環境中數據是千萬或者億級別的時候性能就會差非常非常非常大。通過簡單的Hint可以解決這個問題。
原文轉自:http://www.orczhou.com/index.php/2013/04/how-mysql-choose-index-in-a-join/