學會使用`EXPLAIN`語句

引言

平常工做中,使用MySQL的機會仍是蠻多的,主要考慮Schema與數據類型優化如何建立索引根據業務場景的查詢優化。這些想必你們都在高性能MySQL這本書中看過,可能也比做者理解的深,本文旨在對EXPLAIN語句使用、分析進行整理。html

EXPLAIN語句是什麼?

官網對於EXPLAIN的做用定義以下:mysql

The EXPLAIN statement provides information about how MySQL executes statements. EXPLAIN works with SELECT, DELETE, INSERT, REPLACE, and UPDATE statements.sql

簡單來說,EXPLAIN語句告訴咱們MySQL如何執行SQL語句,而咱們經過這些信息,能夠達到優化SQL語句執行效率的目的。數據庫

接下來,就要對EXPLAIN返回的格式進行了解了,具體以下:ide

字段名 字段描述
id 查詢語句內SELECT的序列號
select_type SELECT類型
table 訪問的表名
partitions 命中分區
type 數據訪問類型,下文詳細介紹
possible_keys 有關索引,實際狀況可能不可用
key MySQL查詢優化器實際使用的索引
key_len 索引存儲長度
ref 實際使用的索引中,用於比較的常量或列
rows 查詢須要讀取的行數,innodb引擎是一個衡量效率的指標,有時可能不許確
Extra 查詢執行的附加信息,下文詳細介紹
  • 在分析SQL語句執行時,主要用到的列,分別爲typeExtra,下文的測試用例均爲官網提供的sakila數據庫,附上下載連接性能

  • 本文使用MySQL 8.0.十二、Navicat 12.1測試

type列主要出現值(性能從好到差)

  • system:表只有一行,const類型的特殊狀況。
  • const:查詢結果最多有一行,多爲主鍵惟一索引與常量比較的狀況。
explain select * from actor where actor_id = 1
複製代碼
  • eq_ref:一種特殊的索引查找,MySQL知道最多隻返回一條符合條件的記錄,使用主鍵NOT NULL的惟一索引會看到(用navicat發現結果也是ref)。
explain select * from actor, film_actor where actor.actor_id = film_actor.actor_id and actor.actor_id = 1
複製代碼
  • ref:一種索引查找,返回全部匹配某個單個值的行,然而,可能會找到多個符合條件的行,當使用非惟一性索引或者惟一性索引的非惟一性前綴時發生。
explain select * from film where title= 'ACE GOLDFINGER'
複製代碼
  • range:範圍掃描就是一個有限制的索引掃描, 不用遍歷全部索引,例如索引在BETWEEN>>範圍內的。
explain select * from film where film_id BETWEEN 1 AND 100
複製代碼
  • index:全表掃描,只是MySQL掃描表時按索引次序而不是行。

Extra列中看到「Using index」,說明是覆蓋索引,只須要讀取索引列,不須要讀取行數據。 使用索引次序全表讀取。優化

explain select actor.actor_id from film_actor, actor where film_actor.actor_id = actor.actor_id 
複製代碼
  • ALL:全表掃描,讀取行數據,找到須要的行。
explain select * from film_actor, actor where film_actor.actor_id = actor.actor_id 
複製代碼

Extra列主要出現的值

  • Using index:使用覆蓋索引,避免回表查詢行數據。
  • Using where:存儲引擎檢索行後再進行過濾。
  • Using temporary:對查詢結果排序時會使用一個臨時表,儘可能避免使用臨時表
  • Using filesort:對結果使用一個外部索引排序,而不是按索引次序從表裏讀取行,須要進行優化

總結

因爲查詢優化器的存在,實際運行查詢語句會和想的不一致,所以在進行查詢語句優化時,最好運行下EXPLAIN語句,看看是否是和本身想的一致。spa

參考文獻

相關文章
相關標籤/搜索