1. 程式人生 > >sql分析命令explain和desc

sql分析命令explain和desc

 explain和desc命令的效果相同,命令格式如下:

mysql> explain SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT  JOIN teacher t ON  s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | s     | index | NULL          | name | 768     | NULL |    3 | Using index                                        |
|  1 | SIMPLE      | t     | ALL   | NULL          | NULL | NULL    | NULL |   10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set

mysql> desc SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT  JOIN teacher t ON  s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | s     | index | NULL          | name | 768     | NULL |    3 | Using index                                        |
|  1 | SIMPLE      | t     | ALL   | NULL          | NULL | NULL    | NULL |   10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set
mysql> explain student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  | MUL | NULL    |                |
| age   | int(11)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set

mysql> desc student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  | MUL | NULL    |                |
| age   | int(11)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+
3 rows in set

 

用於資料表:

mysql> desc student;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(255) | YES  | MUL | NULL    |                |
| age   | int(11)      | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+


Field:表中的欄位名
Type:欄位對應的型別
Null:可否為空
Key:鍵型別,主鍵、索引鍵。。。
Default:預設值
Extra:其他資訊

用於sql:


mysql> explain SELECT s.id sid, s.name sname , t.id tid ,t.name tname FROM student s LEFT  JOIN teacher t ON  s.name = t.name;
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                                              |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+
|  1 | SIMPLE      | s     | index | NULL          | name | 768     | NULL |    3 | Using index                                        |
|  1 | SIMPLE      | t     | ALL   | NULL          | NULL | NULL    | NULL |   10 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+-------+---------------+------+---------+------+------+----------------------------------------------------+

id:查詢的序列號

select_type:查詢的型別,普通查詢、聯合查詢、子查詢等

table:輸出行所引用的表名

type:聯合查詢的訪問型別,此屬性比較重要

possible_keys:表示能使用哪個索引在該表中找到行

key:實際使用的索引鍵,如果沒有索引被選擇,鍵是NULL

key_len:實際使用的鍵長度

ref:顯示哪個欄位或常數與key一起被使用進行查詢

rows:表示要遍歷多少資料才能找到滿足條件的資料,在innodb上是不準確的

extra:附加資訊

著重解釋:

select_type欄位:

SIMPLE 簡單查詢,不適用UNION或子查詢
PRIMARY 最外層的SELECT
UNION UNION中的第二個或後面的SELECT語句
DEPENDENT UNION UNION中的第二個或後面的SELECT語句,取決於外面的查詢
UNION RESULT UNION的結果
SUBQUERY 子查詢中的第一個SELECT
DEPENDENT SUBQUERY 子查詢中的第一個SELECT,取決於外面的查詢
DERIVED FROM子句的子查詢

 

type欄位:

SYSTEM 表中只有一行記錄
CONST 表中最多隻有一行匹配的記錄,他在查詢一開始就會被讀取出來,被作為一個恆定值
EQ_REF 表中會有一行記錄被讀取出來和以前一個表中讀取出來的記錄做聯合,這是最好的連線型別,他用在索引所有欄位都用於做連線並且這個索引是primary key或unique型別
REF 表中所有符合檢索值的記錄都會被取出來和從上一個表中取出來的記錄做聯合,用於連線程式無法根據鍵值只取得一條記錄的情況
REF_OR_NULL 和REF類似,在檢索的時候會搜尋NULL值的記錄,經常用於子查詢
UNIQUE_SUBQUERY 帶in的子查詢來代替ref
INDEX_SUBQUERY 用子查詢來代替in
RANGE 只有在給定範圍的記錄才會被取出來,利用索引來取得一條記錄,key欄位表示使用了那個索引
INDEX 只掃描所引樹
ALL 對錶做全部掃描,應儘量避免

extra欄位:

DISTINCT 找到當前記錄的匹配聯合結果的第一條記錄之後,不再搜尋其他記錄
NOT EXISTS 做一個left join優化,在當前表中找到和前一條記錄符合left join條件後,就不再搜尋更多的記錄
RANGE CHECKED FOR EACH RECORD (INDEX MAP:#) 沒有找到合適的可用的索引,取代的辦法是:對於前一個表的每一個行連線,它會做一個校驗以決定該使用那個索引,並且使用這個索引來從表中取得記錄。
USING FILESORT 需要額外做一遍排序操作,以拍好的順序取得記錄,應儘量避免
USING INDEX 直接從索引樹中的資訊取得記錄,不再去掃描實際的記錄
USING TEMPORARY 建立臨時表儲存結果以完成查詢,通常發生在查詢時包含了group by和order by子句,應儘量避免
USING WHERE where子句將用來限制哪些記錄匹配了下一個表或者傳送到客戶端

可通過上述對錶和sql分析來進行對應的修改,以使得效能達到最優