MySQL 的 EXPLAIN 命令能夠查看SELECT語句的執行的計劃,是 MySQL 查詢優化的必備工具。sql
經過執行計劃能夠了解查詢方式、索引使用狀況、須要掃描的數據量以及是否須要臨時表或排序操做等信息。數據庫
咱們須要分析執行計劃對查詢進行有的放矢的優化。緩存
須要注意:服務器
本文基於 MySQL 5.6 版本。函數
EXPLAIN SELECT * FROM `user` JOIN `post` ON `user`.id = `post`.uid WHERE user.`created_at` < '2018-10-01 00:00:00' AND `post`.status = 1;
結果:工具
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | range | PRIMARY,idx_created_at | idx_created_at | 7 | null | 19440 | Using index condition; Using where; Using temporary; Using filesort |
1 | SIMPLE | post | ref | idx_uid,idx_status | idx_uid | 8 | user.id | 1 | Using where |
EXPLAIN 的行數爲查詢涉及的表數, 結果各列的含義爲:post
select_type 可能的值有:優化
下面給出幾個示例:ui
EXPLAIN SELECT * FROM post WHERE uid = ( SELECT id FROM user WHERE name = "finley" );
id | select_type | table |
---|---|---|
1 | PRIMARY | post |
2 | SUBQUERY | user |
DEPENDENT SUBQUERY:code
EXPLAIN SELECT * FROM post WHERE uid = ( SELECT id FROM user WHERE name = "finley" AND post.uid=user.id );
id | select_type | table |
---|---|---|
1 | PRIMARY | post |
2 | DEPENDENT SUBQUERY | user |
type 字段描述了查詢的方式,從好到壞爲:
SELECT 1;
const: 表中僅有一行匹配,在分解查詢計劃時直接將其讀出做爲常量使用。system 是 const 類型的特例。
示例:SELECT id FROM user WHERE name = "hdt3213";
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | const | uni_name | uni_name | 258 | const | 1 | Using index |
UNIQUE KEY uni_name (name) ON user
eq_ref: 使用 PRIMARY KEY 或 UNIQUE KEY 進行關聯查詢。
示例: SELECT * FROM post JOIN user ON post.uid = user.id WHERE user.gender = 'M';
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | post | ALL | idx_uid | 0 | 0 | 0 | 57796 | null |
1 | SIMPLE | user | eq_ref | PRIMARY | PRIMARY | 8 | post.uid | 1 | Using where |
ref: 使用容許重複的索引進行查詢
示例: SELECT * FROM user WHERE phone='12345678901';
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | ref | idx_phone | idx_phone | 259 | const | 1 | Using index condition |
range: 使用索引進行範圍查詢:
示例: SELECT * FROM user WHERE age>18;
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | ref | idx_age | idx_age | 259 | const | 1 | null |
index: 在索引上進行順序掃描。常見於在多列索引中未使用最左列進行查詢。
示例: SELECT * FROM user WHERE last_name='smith'
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | user | ref | idx_full_name | idx_full_name | 259 | const | 1 | Using where |
all: 掃描全表,最壞的狀況
extra 列顯示了查詢過程當中須要執行的其它操做,有些狀況應盡力避免。