explain select host,user,plugin from user ; +----+-------------+-------+------+---------------+------+---------+------+..."/>
溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

mysql之 explain、optimizer_trace 執(zhí)行計劃

發(fā)布時間:2020-08-12 18:11:07 來源:ITPUB博客 閱讀:161 作者:張沖andy 欄目:MySQL數(shù)據(jù)庫

一、explain

 mysql> explain select host,user,plugin from user ;
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
| 1 | SIMPLE | user | ALL | NULL | NULL | NULL | NULL | 5 | NULL |
+----+-------------+-------+------+---------------+------+---------+------+------+-------+
1 row in set (0.00 sec)

  1.id

  1.SQL執(zhí)行順序:從大到小的執(zhí)行.如果相等先執(zhí)行上面的,再執(zhí)行下面的。(id號為sql代碼中select從左到右出現(xiàn)的順序號)
  
  2. select_type就是select類型,可以有以下幾種
  (1) SIMPLE
  簡單Select(不使用UNION或子查詢等) 例如: 
程序代碼
mysql> explain select * from t3 where id=3952602; 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+ 
  | 1 | SIMPLE | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

  (2). PRIMARY
  最外層的select.例如:
程序代碼
mysql> explain select * from (select * from t3 where id=3952602) a ; 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | | 
  | 2 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

  (3).UNION
  UNION中的第二個或后面的Select語句.例如
程序代碼
mysql> explain select * from t3 where id=3952602 union all select * from t3 ; 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+ 
  | 1 | PRIMARY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | | 
  | 2 | UNION | t3 | ALL | NULL | NULL | NULL | NULL | 1000 | | 
  |NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | | 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

  (4).DEPENDENT UNION
  UNION中的第二個或后面的Select語句,取決于外面的查詢
程序代碼
mysql> explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3) ; 
  +----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
  | 1 | PRIMARY | t3 | ALL | NULL | NULL | NULL | NULL | 1000 | Using where | 
  | 2 | DEPENDENT SUBQUERY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | Using index | 
  | 3 | DEPENDENT UNION | t3 | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4 | func | 1 | Using where; Using index | 
  |NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | | 
  +----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+


  (5).UNION RESULT
  UNION的結(jié)果。
程序代碼
mysql> explain select * from t3 where id=3952602 union all select * from t3 ; 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+ 
  | 1 | PRIMARY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | | 
  | 2 | UNION | t3 | ALL | NULL | NULL | NULL | NULL | 1000 | | 
  |NULL | UNION RESULT | | ALL | NULL | NULL | NULL | NULL | NULL | | 
  +----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

  (6).SUBQUERY
  子查詢中的第一個Select.
程序代碼
mysql> explain select * from t3 where id = (select id from t3 where id=3952602 ) ; 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+ 
  | 1 | PRIMARY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | | 
  | 2 | SUBQUERY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | Using index | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+

  (7). DEPENDENT SUBQUERY
  子查詢中的第一個Select,取決于外面的查詢
程序代碼
mysql> explain select id from t3 where id in (select id from t3 where id=3952602 ) ; 
  +----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+ 
  | 1 | PRIMARY | t3 | index | NULL | PRIMARY | 4 | NULL | 1000 | Using where; Using index | 
  | 2 | DEPENDENT SUBQUERY | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | Using index | 
  +----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+

  (8).DERIVED
  派生表的Select(FROM子句的子查詢) 
程序代碼
mysql> explain select * from (select * from t3 where id=3952602) a ; 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | | 
  | 2 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

  3.table
  顯示這一行的數(shù)據(jù)是關(guān)于哪張表的.
  有時不是真實的表名字,看到的是derivedx(x是個數(shù)字,行記錄引用的衍生表id值) 
程序代碼
mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b; 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | | 
  | 2 | DERIVED | | system | NULL | NULL | NULL | NULL | 1 | | 
  | 3 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

  4.type
  這列很重要,顯示了連接使用了哪種類別,有無使用索引.
  從最好到最差的連接類型為const、eq_reg、ref、range、indexhe和ALL
  (1).system
  這是const聯(lián)接類型的一個特例。表僅有一行滿足條件.如下(t3表上的id是 primary key)
程序代碼
mysql> explain select * from (select * from t3 where id=3952602) a ; 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+ 
  | 1 | PRIMARY | | system | NULL | NULL | NULL | NULL | 1 | | 
  | 2 | DERIVED | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | | 1 | | 
  +----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
  (2).const
  表最多有一個匹配行,它將在查詢開始時被讀取。因為僅有一行,在這行的列值可被優(yōu)化器剩余部分認(rèn)為是常數(shù)。const表很快,因為它們只讀取一次!
  const用于用常數(shù)值比較PRIMARY KEY或UNIQUE索引的所有部分時。在下面的查詢中,tbl_name可以用于const表:
程序代碼
Select * from tbl_name Where primary_key=1; 
Select * from tbl_name Where primary_key_part1=1和 primary_key_part2=2;

  例如:
程序代碼
mysql> explain select * from t3 where id=3952602; 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+ 
  | 1 | SIMPLE | t3 | const | PRIMARY,idx_t3_id | PRIMARY | 4 | const | 1 | | 
  +----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+


  (3). eq_ref
  對于每個來自于前面的表的行組合,從該表中讀取一行。這可能是最好的聯(lián)接類型,除了const類型。它用在一個索引的所有部分被聯(lián)接使用并且索引是UNIQUE或PRIMARY KEY。
  eq_ref可以用于使用= 操作符比較的帶索引的列。比較值可以為常量或一個使用在該表前面所讀取的表的列的表達(dá)式。
  在下面的例子中,MySQL可以使用eq_ref聯(lián)接來處理ref_tables:
程序代碼
Select * FROM ref_table,other_table 
  Where ref_table.key_column=other_table.column; 
  Select * FROM ref_table,other_table 
  Where ref_table.key_column_part1=other_table.column 
  AND ref_table.key_column_part2=1;

  例如
程序代碼
mysql> create unique index idx_t3_id on t3(id) ; 
  Query OK, 1000 rows affected (0.03 sec) 
  Records: 1000 Duplicates: 0 Warnings: 0 
  mysql> explain select * from t3,t4 where t3.id=t4.accountid; 
  +----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+ 
  | 1 | SIMPLE | t4 | ALL | NULL | NULL | NULL | NULL | 1000 | | 
  | 1 | SIMPLE | t3 | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4 | dbatest.t4.accountid | 1 | | 
  +----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+

  (4).ref
  對于每個來自于前面的表的行組合,所有有匹配索引值的行將從這張表中讀取。如果聯(lián)接只使用鍵的最左邊的前綴,或如果鍵不是UNIQUE或PRIMARY KEY(換句話說,如果聯(lián)接不能基于關(guān)鍵字選擇單個行的話),則使用ref。如果使用的鍵僅僅匹配少量行,該聯(lián)接類型是不錯的。
  ref可以用于使用=或<=>操作符的帶索引的列。
  在下面的例子中,MySQL可以使用ref聯(lián)接來處理ref_tables:
程序代碼
Select * FROM ref_table Where key_column=expr; 
Select * FROM ref_table,other_table 
Where ref_table.key_column=other_table.column; 
Select * FROM ref_table,other_table 
Where ref_table.key_column_part1=other_table.column 
AND ref_table.key_column_part2=1;

  例如:
程序代碼
mysql> drop index idx_t3_id on t3; 
  Query OK, 1000 rows affected (0.03 sec) 
  Records: 1000 Duplicates: 0 Warnings: 0 
  mysql> create index idx_t3_id on t3(id) ; 
  Query OK, 1000 rows affected (0.04 sec) 
  Records: 1000 Duplicates: 0 Warnings: 0 
  mysql> explain select * from t3,t4 where t3.id=t4.accountid; 
  +----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+ 
  | 1 | SIMPLE | t4 | ALL | NULL | NULL | NULL | NULL | 1000 | | 
  | 1 | SIMPLE | t3 | ref | PRIMARY,idx_t3_id | idx_t3_id | 4 | dbatest.t4.accountid | 1 | | 
  +----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+ 
  2 rows in set (0.00 sec)

  (5). ref_or_null
  該聯(lián)接類型如同ref,但是添加了MySQL可以專門搜索包含NULL值的行。在解決子查詢中經(jīng)常使用該聯(lián)接類型的優(yōu)化。
  在下面的例子中,MySQL可以使用ref_or_null聯(lián)接來處理ref_tables:
Select * FROM ref_table 
Where key_column=expr or key_column IS NULL;

  (6). index_merge
  該聯(lián)接類型表示使用了索引合并優(yōu)化方法。在這種情況下,key列包含了使用的索引的清單,key_len包含了使用的索引的最長的關(guān)鍵元素。
  例如:
程序代碼
mysql> explain select * from t4 where id=3952602 or accountid=31754306 ; 
  +----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+ 
  | 1 | SIMPLE | t4 | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4 | NULL | 2 | Using union(idx_t4_id,idx_t4_accountid); Using where | 
  +----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+ 
  1 row in set (0.00 sec)

  (7). unique_subquery
  該類型替換了下面形式的IN子查詢的ref:
value IN (Select primary_key FROM single_table Where some_expr)

  unique_subquery是一個索引查找函數(shù),可以完全替換子查詢,效率更高。
  (8).index_subquery
  該聯(lián)接類型類似于unique_subquery??梢蕴鎿QIN子查詢,但只適合下列形式的子查詢中的非唯一索引:
程序代碼
value IN (Select key_column FROM single_table Where some_expr)


  (9).range
  只檢索給定范圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引。key_len包含所使用索引的最長關(guān)鍵元素。在該類型中ref列為NULL。
  當(dāng)使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比較關(guān)鍵字列時,可以使用range
程序代碼
mysql> explain select * from t3 where id=3952602 or id=3952603 ; 
  +----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+ 
  | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | 
  +----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+ 
  | 1 | SIMPLE | t3 | range | PRIMARY,idx_t3_id | idx_t3_id | 4 | NULL | 2 | Using where | 
  +----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+ 
  1 row in set (0.02 sec)
  (10).index

  該聯(lián)接類型與ALL相同,除了只有索引樹被掃描。這通常比ALL快,因為索引文件通常比數(shù)據(jù)文件小。
  當(dāng)查詢只使用作為單索引一部分的列時,MySQL可以使用該聯(lián)接類型。
  (11). ALL
  對于每個來自于先前的表的行組合,進(jìn)行完整的表掃描。如果表是第一個沒標(biāo)記const的表,這通常不好,并且通常在它情況下很差。通??梢栽黾痈嗟乃饕灰褂肁LL,使得行能基于前面的表中的常數(shù)值或列值被檢索出。
  5.possible_keys
  possible_keys列指出MySQL能使用哪個索引在該表中找到行。注意,該列完全獨立于EXPLAIN輸出所示的表的次序。這意味著在possible_keys中的某些鍵實際上不能按生成的表次序使用。
  如果該列是NULL,則沒有相關(guān)的索引。在這種情況下,可以通過檢查Where子句看是否它引用某些列或適合索引的列來提高你的查詢性能。如果是這樣,創(chuàng)造一個適當(dāng)?shù)乃饕⑶以俅斡肊XPLAIN檢查查詢
  6. key
  key列顯示MySQL實際決定使用的鍵(索引)。如果沒有選擇索引,鍵是NULL。要想強(qiáng)制MySQL使用或忽視possible_keys列中的索引,在查詢中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。
  7.key_len
  key_len列顯示MySQL決定使用的鍵長度。如果鍵是NULL,則長度為NULL。
  使用的索引的長度。在不損失精確性的情況下,長度越短越好
  8. ref
  ref列顯示使用哪個列或常數(shù)與key一起從表中選擇行。
  9. rows
  rows列顯示MySQL認(rèn)為它執(zhí)行查詢時必須檢查的行數(shù)。
  10. Extra
  該列包含MySQL解決查詢的詳細(xì)信息,下面詳細(xì).
  (1).Distinct
  一旦MYSQL找到了與行相聯(lián)合匹配的行,就不再搜索了
  (2).Not exists
  MYSQL優(yōu)化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標(biāo)準(zhǔn)的行,
  就不再搜索了
  (3).Range checked for each
  Record(index map:#)
  沒有找到理想的索引,因此對于從前面表中來的每一個行組合,MYSQL檢查使用哪個索引,并用它來從表中返回行。這是使用索引的最慢的連接之一
  (4).Using filesort
  看到這個的時候,查詢就需要優(yōu)化了。MYSQL需要進(jìn)行額外的步驟來發(fā)現(xiàn)如何對返回的行排序。它根據(jù)連接類型以及存儲排序鍵值和匹配條件的全部行的行指針來排序全部行
  (5).Using index
  列數(shù)據(jù)是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發(fā)生在對表的全部的請求列都是同一個索引的部分的時候
  (6).Using temporary
  看到這個的時候,查詢需要優(yōu)化了。這里,MYSQL需要創(chuàng)建一個臨時表來存儲結(jié)果,這通常發(fā)生在對不同的列集進(jìn)行ORDER BY上,而不是GROUP BY上
  (7).Using where
  使用了Where從句來限制哪些行將與下一張表匹配或者是返回給用戶。如果不想返回表中的全部行,并且連接類型ALL或index,這就會發(fā)生,或者是查詢有問題


二、 optimizer_trace

從MySQL5.6版本開始,optimizer_trace 可支持把MySQL查詢執(zhí)行計劃樹打印出來,對DBA深入分析SQL執(zhí)行計劃,COST成本都非常有用,打印的內(nèi)部信息比較全面。默認(rèn)是關(guān)閉的,功能支持動態(tài)開關(guān),因為對性能有20%左右影響,只建議分析問題時,臨時開啟。

1. 默認(rèn)是關(guān)閉的
mysql> show variables like 'optimizer_trace';
+-----------------+--------------------------+
| Variable_name | Value |
+-----------------+--------------------------+
| optimizer_trace | enabled=off,one_line=off |
+-----------------+--------------------------+
1 row in set (0.05 sec)

2.演示 optimizer_trace 簡單的使用流程:
2.1 會話級別臨時開啟
mysql> set session optimizer_trace="enabled=on",end_markers_in_json=on;
2.2 執(zhí)行你的SQL
select host,user,plugin from user ;
2.3 查詢information_schema.optimizer_trace表
mysql> SELECT trace FROM information_schema.OPTIMIZER_TRACE\G;
2.4 導(dǎo)入到一個命名為xx.trace的文件,然后用JSON閱讀器來查看 
SELECT TRACE INTO DUMPFILE “xx.trace” FROM INFORMATION_SCHEMA.OPTIMIZER_TRACE;

補(bǔ)充:永久開啟 optimizer_trace   (重啟失效)
mysql> set optimizer_trace="enabled=on";


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI