1. 程式人生 > >MySQL EXPLAIN 命令詳解

MySQL EXPLAIN 命令詳解

 在工作中,我們用於捕捉效能問題最常用的就是開啟慢查詢,定位執行效率差的SQL,那麼當我們定位到一個SQL以後還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃描,這些都需要通過EXPLAIN去完成。EXPLAIN命令是檢視優化器如何決定執行查詢的主要方法。可以幫助我們深入瞭解MySQL的基於開銷的優化器,還可以獲得很多可能被優化器考慮到的訪問策略的細節,以及當執行SQL語句時哪種策略預計會被優化器採用。需要注意的是,生成的QEP並不確定,它可能會根據很多因素髮生改變。MySQL不會將一個QEP和某個給定查詢繫結,QEP將由SQL語句每次執行時的實際情況確定,即便使用儲存過程也是如此。儘管在儲存過程中SQL語句都是預先解析過的,但QEP仍然會在每次呼叫儲存過程的時候才被確定。

([email protected]) [test]>explain select d1.age, t2.id from (select age,name from t1 where id in (1,2))d1, t2 where d1.age=t2.age group by d1.age, t2.id order by t2.id;
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref    | rows | Extra                           |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL   |    2 | Using temporary; Using filesort |
|  1 | PRIMARY     | t2         | ref   | age           | age     | 5       | d1.age |    1 | Using where; Using index        |
|  2 | DERIVED     | t1         | range | PRIMARY       | PRIMARY | 4       | NULL   |    2 | Using where                     |
+----+-------------+------------+-------+---------------+---------+---------+--------+------+---------------------------------+
rows in set (0.00 sec)

(
[email protected]
) [test]>

MySQL執行計劃呼叫方式
1.EXPLAIN SELECT ……
變體:
2.EXPLAIN EXTENDED SELECT ……
將執行計劃"反編譯"成SELECT語句,執行SHOW WARNINGS 
可得到被MySQL優化器優化後的查詢語句
3.EXPLAIN PARTITIONS SELECT ……
用於分割槽表的EXPLAIN生成QEP的資訊

執行計劃包含的資訊

+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+

1. id:

包含一組數字,表示查詢中執行select子句或操作表的順序

Example(id相同,執行順序由上至下

([email protected]) [test]>explain select t2.* from t1, t2, t3 where t1.id=t2.id and t1.id=t3.id and t1.name='';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra                    |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
|  1 | SIMPLE      | t1    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where; Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 |                          |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index              |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+--------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

Example (如果是子查詢,id的序號會遞增,id值越大優先順序越高,越先被執行)

([email protected]) [test]>explain select t2.* from t2 where id = (select id from t1 where id = (select t3.id from t3 where t3.name=''));
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                                               |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
|  1 | PRIMARY     | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE noticed after reading const tables |
|  2 | SUBQUERY    | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | no matching row in const table                      |
|  3 | SUBQUERY    | t3    | ref  | name          | name | 63      |      |    1 | Using where; Using index                            |
+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

Example(id如果相同,可以認為是一組,從上往下順序執行;在所有組中,id值越大,優先順序越高,越先執行)

([email protected]) [test]>explain select t2.* from (select t3.id from t3 where t3.name='')s1, t2 where s1.id=t2.id;
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref   | rows | Extra                    |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL  |    1 |                          |
|  1 | PRIMARY     | t2         | const  | PRIMARY       | PRIMARY | 4       | const |    1 |                          |
|  2 | DERIVED     | t3         | ref    | name          | name    | 63      |       |    1 | Using where; Using index |
+----+-------------+------------+--------+---------------+---------+---------+-------+------+--------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

2. select_type

示查詢中每個select子句的型別(簡單OR複雜)

a. SIMPLE:查詢中不包含子查詢或者UNION
b. 查詢中若包含任何複雜的子部分,最外層查詢則被標記為:PRIMARY
c. 在SELECT或WHERE列表中包含了子查詢,該子查詢被標記為:SUBQUERY
d. 在FROM列表中包含的子查詢被標記為:DERIVED(衍生)用來表示包含在from子句中的子查詢的select,mysql會遞迴執行並將結果放到一個臨時表中。伺服器內部稱為"派生表",因為該臨時表是從子查詢中派生出來的
e. 若第二個SELECT出現在UNION之後,則被標記為UNION;若UNION包含在FROM子句的子查詢中,外層SELECT將被標記為:DERIVED
f. 從UNION表獲取結果的SELECT被標記為:UNION RESULT

SUBQUERY和UNION還可以被標記為DEPENDENT和UNCACHEABLE。
DEPENDENT意味著select依賴於外層查詢中發現的資料。
UNCACHEABLE意味著select中的某些 特性阻止結果被緩存於一個item_cache中。

Example

([email protected]) [test]>explain select d1.name, ( select id from t3) d2 from (select id,name from t1 where name='')d1 union (select name,id from t2);
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
| id | select_type  | table      | type   | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
|  1 | PRIMARY      | <derived3> | system | NULL          | NULL | NULL    | NULL |    0 | const row not found      |
|  3 | DERIVED      | t1         | ref    | name          | name | 63      |      |    1 | Using where; Using index |
|  2 | SUBQUERY     | t3         | index  | NULL          | age  | 5       | NULL |    6 | Using index              |
|  4 | UNION        | t2         | index  | NULL          | name | 63      | NULL |    4 | Using index              |
| NULL | UNION RESULT | <union1,4> | ALL    | NULL          | NULL | NULL    | NULL | NULL |                          |
+----+--------------+------------+--------+---------------+------+---------+------+------+--------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

第一行:id列為1,表示第一個select,select_type列的primary表 示該查詢為外層查詢,table列被標記為<derived3>,表示查詢結果來自一個衍生表,其中3代表該查詢衍生自第三個select查詢,即id為3的select。
第二行:id為3,表示該查詢的執行次序為2( 4 => 3),是整個查詢中第三個select的一部分。因查詢包含在from中,所以為derived。
第三行:select列表中的子查詢,select_type為subquery,為整個查詢中的第二個select。
第四行:select_type為union,說明第四個select是union裡的第二個select,最先執行。
第五行:代表從union的臨時表中讀取行的階段,table列的<union1,4>表示用第一個和第四個select的結果進行union操作。

3. type                                       

表示MySQL在表中找到所需行的方式,又稱“訪問型別”,常見型別如下:

 ALL, index,  range, ref, eq_ref, const, system, NULL

從左到右,效能從最差到最好

Example

a. ALL:Full Table Scan, MySQL將遍歷全表以找到匹配的行

([email protected]) [test]>explain select * from t1 where email='';
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

b. index:Full Index Scan,index與ALL區別為index型別只遍歷索引樹

([email protected]) [test]>explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

c. range:索引範圍掃描,對索引的掃描開始於某一點,返回匹配值域的行。顯而易見的索引範圍掃描是帶有between或者where子句裡帶有<, >查詢。當mysql使用索引去查詢一系列值時,例如IN()和OR列表,也會顯示range(範圍掃描),當然效能上面是有差異的。

([email protected]) [test]>explain select * from t1 where id in (1,4);
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>explain select * from t1 where id between 1 and 4;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>explain select * from t1 where id=1 or id=4;       
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
row in set (0.01 sec)

([email protected]) [test]>explain select * from t1 where id > 1;      
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    3 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

d. ref:使用非唯一索引掃描或者唯一索引的字首掃描,返回匹配某個單獨值的記錄行

([email protected]) [test]>explain select * from t1 where name='yayun';
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
|  1 | SIMPLE      | t1    | ref  | name          | name | 63      | const |    1 | Using where |
+----+-------------+-------+------+---------------+------+---------+-------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

e. eq_ref:類似ref,區別就在使用的索引是唯一索引,對於每個索引鍵值,表中只有一條記錄匹配,簡單來說,就是多表連線中使用primary key或者 unique key作為關聯條件

([email protected]) [test]>explain select t1.name from t1, t2 where t1.id=t2.id;
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t1    | index  | PRIMARY       | name    | 63      | NULL       |    4 | Using index |
|  1 | SIMPLE      | t2    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t1.id |    1 | Using index |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
rows in set (0.00 sec)

([email protected]) [test]>

f. const、system:當MySQL對查詢某部分進行優化,並轉換為一個常量時,使用這些型別訪問。如將主鍵置於where列表中,MySQL就能將該查詢轉換為一個常量

([email protected]) [test]>explain select * from ( select * from t1 where id=1)b1;
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL          | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t1         | const  | PRIMARY       | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+---------------+---------+---------+------+------+-------+
rows in set (0.00 sec)

([email protected]) [test]>

注:system是const型別的特例,當查詢的表只有一行的情況下,使用system

g. NULL:MySQL在優化過程中分解語句,執行時甚至不用訪問表或索引,例如從一個索引列裡選取最小值可以通過單獨索引查詢完成。

([email protected]) [test]>explain select * from t1 where id = (select min(id) from t2);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra                        |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
|  1 | PRIMARY     | t1    | const | PRIMARY       | PRIMARY | 4       | const |    1 |                              |
|  2 | SUBQUERY    | NULL  | NULL  | NULL          | NULL    | NULL    | NULL  | NULL | Select tables optimized away |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

4. possible_keys
指出MySQL能使用哪個索引在表中找到記錄,查詢涉及到的欄位上若存在索引,則該索引將被列出,但不一定被查詢使用

5. key
顯示MySQL在查詢中實際使用的索引,若沒有使用索引,顯示為NULL

Example

([email protected]) [test]>explain select id,age from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

6. key_len
表示索引中使用的位元組數,可通過該列計算查詢中使用的索引的長度(key_len顯示的值為索引欄位的最大可能長度,並非實際使用長度,即key_len是根據表定義計算而得,不是通過表內檢索出的)

7. ref
表示上述表的連線匹配條件,即哪些列或常量被用於查詢索引列上的值

8. rows
表示MySQL根據表統計資訊及索引選用情況,估算的找到所需的記錄所需
要讀取的行數

Example   

([email protected]) [test]>explain select * from t1 , t2 where t1.id=t2.id and t2.name='atlas';
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref        | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
|  1 | SIMPLE      | t2    | ref    | PRIMARY,name  | name    | 63      | const      |    1 | Using where |
|  1 | SIMPLE      | t1    | eq_ref | PRIMARY       | PRIMARY | 4       | test.t2.id |    1 |             |
+----+-------------+-------+--------+---------------+---------+---------+------------+------+-------------+
rows in set (0.00 sec)

([email protected]) [test]>

9. Extra
包含不適合在其他列中顯示但十分重要的額外資訊
a. Using index
該值表示相應的select操作中使用了覆蓋索引(Covering Index)

Example

([email protected]) [test]>explain select id from t1;
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

覆蓋索引(Covering Index)
MySQL可以利用索引返回select列表中的欄位,而不必根據索引再次讀取資料檔案
包含所有滿足查詢需要的資料的索引稱為覆蓋索引(Covering Index)
注意:如果要使用覆蓋索引,一定要注意select列表中只取出需要的列,不可select *,因為如果將所有欄位一起做索引會導致索引檔案過大,查詢效能下降

b. Using where
表示mysql伺服器將在儲存引擎檢索行後再進行過濾。許多where條件裡涉及索引中的列,當(並且如果)它讀取索引時,就能被儲存引擎檢驗,因此不是所有帶where字句的查詢都會顯示"Using where"。有時"Using where"的出現就是一個暗示:查詢可受益與不同的索引。

Example

([email protected]) [test]>explain select id,name from t1 where id<4;
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | PRIMARY       | name | 63      | NULL |    4 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+--------------------------+
row in set (0.00 sec)

([email protected]) [test]>

c. Using temporary
表示MySQL需要使用臨時表來儲存結果集,常見於排序和分組查詢

這個值表示使用了內部臨時(基於記憶體的)表。一個查詢可能用到多個臨時表。有很多原因都會導致MySQL在執行查詢期間建立臨時表。兩個常見的原因是在來自不同表的上使用了DISTINCT,或者使用了不同的ORDER BY和GROUP BY列。可以強制指定一個臨時表使用基於磁碟的MyISAM儲存引擎。這樣做的原因主要有兩個:
1)內部臨時表佔用的空間超過min(tmp_table_size,max_heap_table_size)系統變數的限制
2)使用了TEXT/BLOB 列

Example

([email protected]) [test]>explain select id from t1 where id in (1,2) group by age,name;
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | t1    | range | PRIMARY       | PRIMARY | 4       | NULL |    2 | Using where; Using temporary; Using filesort |
+----+-------------+-------+-------+---------------+---------+---------+------+------+----------------------------------------------+
1 row in set (0.00 sec)

([email protected]) [test]>

d. Using filesort
MySQL中無法利用索引完成的排序操作稱為“檔案排序”

Example

([email protected]) [test]>explain select id,age from t1 order by name; 
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra          |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
row in set (0.00 sec)

([email protected]) [test]>explain select id,age from t1 order by age; 
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | t1    | index | NULL          | age  | 5       | NULL |    4 | Using index |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
row in set (0.00 sec)

([email protected]) [test]>

e. Using join buffer
改值強調了在獲取連線條件時沒有使用索引,並且需要連線緩衝區來儲存中間結果。如果出現了這個值,那應該注意,根據查詢的具體情況可能需要新增索引來改進能。

Example

([email protected]) [test]>explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref          | rows | Extra                    |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
|  1 | SIMPLE      | t1    | index | name          | name | 63      | NULL         |    4 | Using index              |
|  1 | SIMPLE      | t2    | ref   | name          | name | 63      | test.t1.name |    2 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+--------------+------+--------------------------+
rows in set (0.00 sec)

([email protected]) [test]>alter table t1 drop key name;                                   
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

([email protected]) [test]>alter table t2 drop key name; 
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

([email protected]) [test]>explain select t1.name from t1 inner join t2 on t1.name=t2.name;
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                          |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
|  1 | SIMPLE      | t1    | ALL  | NULL          | NULL | NULL    | NULL |    4 |                                |
|  1 | SIMPLE      | t2    | ALL  | NULL          | NULL | NULL    | NULL |    4 | Using where; Using join buffer |
+----+-------------+-------+------+---------------+------+---------+------+------+--------------------------------+
rows in set (0.00 sec)

([email protected]) [test]>

f. Impossible where
這個值強調了where語句會導致沒有符合條件的行。

Example

([email protected]) [test]>EXPLAIN SELECT * FROM t1 WHERE 1=2;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra            |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Impossible WHERE |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------+
row in set (0.00 sec)

([email protected]) [test]>

h. Select tables optimized away
這個值意味著僅通過使用索引,優化器可能僅從聚合函式結果中返回一行.

Example

([email protected]) [test]>explain select max(id) from t1;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
row in set (0.00 sec)

([email protected]) [test]>

I. Index merges
當MySQL 決定要在一個給定的表上使用超過一個索引的時候,就會出現以下格式中的一個,詳細說明使用的索引以及合併的型別。
Using sort_union(...)
Using union(...)
Using intersect(...)

總結:
• EXPLAIN不會告訴你關於觸發器、儲存過程的資訊或使用者自定義函式對查詢的影響情況
• EXPLAIN不考慮各種Cache
• EXPLAIN不能顯示MySQL在執行查詢時所作的優化工作
• 部分統計資訊是估算的,並非精確值
• EXPALIN只能解釋SELECT操作,其他操作要重寫為SELECT後檢視執行計劃。

相關推薦

MYSQL-EXPLAIN 命令 (轉載)

test cacheable sel exp 打開慢 一起 select語句 方式 命令詳解 在工作中,我們用於捕捉性能問題最常用的就是打開慢查詢,定位執行效率差的SQL,那麽當我們定位到一個SQL以後還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃

MySQL EXPLAIN 命令

 在工作中,我們用於捕捉效能問題最常用的就是開啟慢查詢,定位執行效率差的SQL,那麼當我們定位到一個SQL以後還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃描,這些都需要通過EXPLAIN去完成。EXPLAIN命令是檢視優化器如何決定執行查詢的主

mysql 學習與提高5:explain命令

目錄 Explain 簡介 Explain 使用 Explain 欄位 1. id欄位 2.select_type 3.table 4.type 5.possible_keys 6.key 7.key_len 8.ref 9.rows 10.ext

EXPLAIN 命令

在工作中,我們用於捕捉效能問題最常用的就是開啟慢查詢,定位執行效率差的SQL,那麼當我們定位到一個SQL以後還不算完事,我們還需要知道該SQL的執行計劃,比如是全表掃描,還是索引掃描,這些都需要通過EXPLAIN去完成。EXPLAIN命令是檢視優化器如何決定執行查詢的主要方法

EXPLAIN命令

id d是用來順序標識整個查詢中SELELCT 語句的,在巢狀查詢中id越大的語句越先執行。該值可能為NULL,如果這一行用來說明的是其他行的聯合結果。 select_type 表示查詢的型別 simple 簡單子查詢,不包含子查詢和union

MySQL常用命令

使用MySQL資料庫 登入到MySQL 當MySQL服務已經執行時,我們可以通過MySQL自帶的客戶端工具登入到MySQL資料庫中,首先開啟終端,輸入以下格式的命令: mysql -h 主機名 -u 使用者名稱 -p -h:該引數用於指定

Ubuntu下Mysql常用命令

Mysql安裝目錄 資料庫目錄 /var/lib/mysql/ 配置檔案 /usr/share/mysql(mysql.server命令及配置檔案) 相關命令 /usr/bin(mysqladmin mysqldump等命令) 啟動指令碼 /et

MySQL show processlist;命令

order by 檢查 否則 操作 locked 等待 inf 可能 增加 SHOW PROCESSLIST顯示哪些線程正在運行,如果您有SUPER權限,您可以看到所有線程,否則,您只能看到您自己的線程(也就是,與您正在使用的MySQL賬戶相關的線程),如果您不使用FULL

MySQL檢視操作命令

MySQL檢視操作命令詳解   建立檢視 在MySQL中,建立檢視的完整語法如下: CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] VIEW view_name [(column_l

MYSQL資料庫基本操作和命令

在學習MySQL資料庫之前我們要知道MySQL資料庫的操作語言的分類; DDL(資料定義語言) 表的定義、使用者的定義… create drop alter DML(資料操控語言) 對資料的增加、修改、刪除、查詢 insert update delete select

mysql匯入匯出命令

mysql匯入匯出命令詳解 一、匯出資料庫用mysqldump命令(注意mysql的安裝路徑,即此命令的路徑):/usr/local/mysql/bin/  --->  mysql的data目錄1、匯出資料和表結構:mysqldump -u使用者名稱 -p密碼 資料庫名 >

Mysql中grant命令

1.遠端登入mysql mysql -h ip -u root -p 密碼 2.建立使用者 格式:grant 許可權 on 資料庫.* to 使用者名稱@登入主機 identified by “密碼”; 例1:增加一個test1使用者,密碼為123456,可以在任何主機上登入,並對所有資料庫有查詢,增加,修

mysql命令

首先建立一個簡單的user表 CREATE TABLE `user` ( `id`  int NOT NULL AUTO_INCREMENT , `name`  varchar(255) NULL , `sex`  varchar(255) NULL , `age`  in

mysql show processlist命令

出處:http://renxiangzyq.iteye.com/blog/835397 processlist 命令的輸出結果顯示了有哪些執行緒在執行,可以幫助識別出有問題的查詢語句,兩種方式使用這個命令。 1.        進入 mysql/bin 目錄下輸入 mysq

MySQL的常用操作命令

系統管理 啟動MySQL服務 通過windows服務管理器啟動MySQL服務 開始-->執行-->輸入services.msc命令-->啟動MySQL服務 通過DOS命令啟動MySQL服務 net start my

tar命令

pan 詳解 time border 設備 lin bsp force names 解壓到指定目錄 tar -zxvf flash_player_npapi_linux.x86_64.tar.gz -C mmtar -zxvf flash_player_npapi_linu

Linux下安裝軟件命令

代碼包 相關信息 make bin 一個 軟件包 輸入 -i bin文件 Linux下軟件安裝方法總結:一、rpm包安裝方式步驟:1、找到相應的軟件包,比如soft.version.rpm,下載到本機某個目錄;2、打開一個終端,su -成root用戶;3、cd soft.v

Docker常用命令

nbsp 詳解 .cn 本地 test 並且 www 更多 top docker ps 查看當前正在運行的容器 docker ps -a 查看所有容器的狀態 docker start/stop id/name 啟動/停止某個容器 docker attach id 進

linux下cat命令

forever ron localhost root sta testing 幫助 查看 一點 1、cat 顯示文件連接文件內容的工具; cat 是一個文本文件查看和連接工具。查看一個文件的內容,用cat比較簡單,就是cat 後面直接接文件名。 比如: de>[[

Linux:at命令

計時 osi 執行 inux days pan 必須 man 一個 at命令 at命令為單一工作調度命令。at命令非常簡單,但是在指定時間上卻非常強大 語法 at [選項] time at > 執行的命令 ctrl+d 選項 -m :當指定的任務被