mysql的sql執行計劃詳解

實際項目開發中,因爲咱們不知道實際查詢的時候數據庫裏發生了什麼事情,數據庫軟件是怎樣掃描表、怎樣使用索引的,所以,咱們能感知到的就只有mysql

sql語句運行的時間,在數據規模不大時,查詢是瞬間的,所以,在寫sql語句的時候就不多考慮到性能的問題。可是當數據規模增大,如千萬、億的時候,咱們運sql

行一樣的sql語句時卻發現遲遲沒有結果,這個時候才知道數據規模已經限制了咱們查詢的速度。因此,查詢優化和索引也就顯得很重要了。數據庫

問題:mysql優化

當咱們在查詢前可否預先估計查詢究竟要涉及多少行、使用哪些索引、運行時間呢?答案是能的,mysql提供了相應的功能和語法來實現該功能。性能

分析:優化

MySql提供了EXPLAIN語法用來進行查詢分析,在SQL語句前加一個"EXPLAIN"便可。好比咱們要分析以下SQL語句:指針

explain select * from table where table.id = 1排序

運行上面的sql語句後你會看到,下面的表頭信息:索引

table | type | possible_keys | key | key_len | ref | rows | Extra開發

EXPLAIN列的解釋

table 顯示這一行的數據是關於哪張表的

type 這是重要的列,顯示鏈接使用了何種類型。從最好到最差的鏈接類型爲const、eq_reg、ref、range、indexhe和ALL

說明:不一樣鏈接類型的解釋(按照效率高低的順序排序)

system:表只有一行:system表。這是const鏈接類型的特殊狀況。

const :表中的一個記錄的最大值可以匹配這個查詢(索引能夠是主鍵或唯一索引)。由於只有一行,這個值實際就是常數,由於MYSQL先讀這個值而後把它當作常數來對待。

eq_ref:在鏈接中,MYSQL在查詢時,從前面的表中,對每個記錄的聯合都從表中讀取一個記錄,它在查詢使用了索引爲主鍵或唯一鍵的所有時使用。

ref:這個鏈接類型只有在查詢使用了不是唯一或主鍵的鍵或者是這些類型的部分(好比,利用最左邊前綴)時發生。對於以前的表的每個行聯合,所有記錄都將從表中讀出。這個類型嚴重依賴於根據索引匹配的記錄多少—越少越好。

range:這個鏈接類型使用索引返回一個範圍中的行,好比使用>或<查找東西時發生的狀況。

index:這個鏈接類型對前面的表中的每個記錄聯合進行徹底掃描(比ALL更好,由於索引通常小於表數據)。

ALL:這個鏈接類型對於前面的每個記錄聯合進行徹底掃描,這通常比較糟糕,應該儘可能避免。

possible_keys 顯示可能應用在這張表中的索引。若是爲空,沒有可能的索引。能夠爲相關的域從WHERE語句中選擇一個合適的語句

key 實際使用的索引。若是爲NULL,則沒有使用索引。不多的狀況下,MYSQL會選擇優化不足的索引。這種狀況下,能夠在SELECT語句中使用USE INDEX(indexname)來強制使用一個索引或者用IGNORE INDEX(indexname)來強制MYSQL忽略索引

key_len 使用的索引的長度。在不損失精確性的狀況下,長度越短越好

ref 顯示索引的哪一列被使用了,若是可能的話,是一個常數

rows MYSQL認爲必須檢查的用來返回請求數據的行數

Extra 關於MYSQL如何解析查詢的額外信息。將在表4.3中討論,但這裏能夠看到的壞的例子是Using temporary和Using filesort,意思MYSQL根本不能使用索引,結果是檢索會很慢

說明:extra列返回的描述的意義

Distinct :一旦mysql找到了與行相聯合匹配的行,就再也不搜索了。

Not exists :mysql優化了LEFT JOIN,一旦它找到了匹配LEFT JOIN標準的行,就再也不搜索了。

Range checked for each Record(index map:#) :沒有找到理想的索引,所以對從前面表中來的每個行組合,mysql檢查使用哪一個索引,並用它來從表中返回行。這是使用索引的最慢的鏈接之一。

Using filesort :看到這個的時候,查詢就須要優化了。mysql須要進行額外的步驟來發現如何對返回的行排序。它根據鏈接類型以及存儲排序鍵值和匹配條件的所有行的行指針來排序所有行。

Using index :列數據是從僅僅使用了索引中的信息而沒有讀取實際的行動的表返回的,這發生在對錶的所有的請求列都是同一個索引的部分的時候。

Using temporary :看到這個的時候,查詢須要優化了。這裏,mysql須要建立一個臨時表來存儲結果,這一般發生在對不一樣的列集進行ORDER BY上,而不是GROUP BY上。

Where used :使用了WHERE從句來限制哪些行將與下一張表匹配或者是返回給用戶。若是不想返回表中的所有行,而且鏈接類型ALL或index,這就會發生,或者是查詢有問題。

所以,弄明白了explain語法返回的每一項結果,咱們就能知道查詢大體的運行時間了,若是查詢裏沒有用到索引、或者須要掃描的行過多,那麼能夠感到明顯的延遲。所以須要改變查詢方式或者新建索引。mysql中的explain語法能夠幫助咱們改寫查詢,優化表的結構和索引的設置,從而最大地提升查詢效率。固然,在大規模數據量時,索引的創建和維護的代價也是很高的,每每須要較長的時間和較大的空間,若是在不一樣的列組合上創建索引,空間的開銷會更大。所以索引最好設置在須要常常查詢的字段中。

相關文章
相關標籤/搜索