MySQL中explain以及索引

一、explain

1. explain含義

通常使用explain關鍵字模擬優化器執行SQL語句,從而瞭解MySQL如何處理SQL語句

2. explain用法

explain + SQL語句

通過explain可以分析出以下結果:
	表的讀取順序
	數據讀取操作的基本類型
	哪些索引可以使用
	哪些索引被實際使用
	表之間的引用
	每張表有多少行被優化器查詢

3. explain出來的信息



    3.1、id(三種情況):select查詢的序列號,包含一組數字,表示查詢中執行select子句或操作表的順序

        ♠ id相同,執行順序由上至下
       
        ♠ id不同,如果是子查詢,id的序號會遞增,id值越大優先級越高,越先被執行
       
        ♠ id既有相同也有不同,同時存在(id相同可以認爲是一個組的,從上往下執行,然後就是,在所有組中,id值越大優先級越高)
       

    3.2 、select_type(由六種類型): 查詢類型,主要用於區別普通查詢、聯合查詢、子查詢等複雜查詢

類型 特性
simple 簡單的select查詢,查詢中不包含子查詢或者UNION
primary 查詢中若包含任何複雜的子部分,最外層查詢則被標記爲PRIMARY
subquery 在SELECT或WHERE列表中包含了子查詢
derived 在FROM列表中包含的子查詢被標記爲DERIVED(衍生),MySQL會遞歸執行這些子查詢,把結果放在臨時表中
union 若第二個SELECT出現在UNION之後,則被標記爲UNION:若UNION包含在FROM子句的子查詢中,外層SELECT將被標記爲:DERIVED
union result 從UNION表獲取結果的SELECT

    3.3 、table

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

    3.4、partitions

相比 explain 多了個 partitions 字段,如果查詢是基於分區表的話,會顯示查詢將訪問的分區

    3.5、type

所顯示的是查詢所使用的那種類型

最好到最差:
system  >  const  >  eq_ref>  ref  >  range  >  index > all
一般來說:保證查詢至少達到range級別,最好能達到ref
類型 特性
system 表只有一行記錄(等於系統表),這是const類型的特例,平時不會出現,這個也可以忽略不計
const 表示通過索引一次就找到了,const用於比較primary key或者unique索引。因此只匹配一行數據,所以很快,如將主鍵置於where列表中,mysql就能將該查詢轉換爲一個常量
eq_ref 唯一性索引掃描,對於每個索引鍵,表中都只有一條記錄與之匹配。常見於主鍵或唯一索引掃描
ref 非唯一性索引掃描,返回匹配某個單獨值的所有行。本質上也是一種索引還能訪問,它返回所有匹配某個單獨值的行,然而,他可能會找到多個符合條件的行,所以他應該屬於查找和掃描的混合體

通俗的解釋:索引非唯一,條件用索引列=xxx
range 只檢索給定範圍的行,使用一個索引來選擇行。key列顯示使用了哪個索引,一般就是在你的where語句中出現了between、<、>、in等的查詢,這種範圍掃描索引掃描比全表掃描要好,因爲它只需要開始於索引的某一點,而結束於另一點,不會掃描全部索引
index Full Index Scan,index與ALL區別爲index類型只遍歷索引樹。這通常比ALL快,因爲索引文件通常比數據文件小。(也就是說雖然all和index都是讀全表,但index是從索引中讀取的,而all是從磁盤中讀取的)

通俗的解釋就是說只查帶索引的字段。
all Full Table Scan,將遍歷全表以找到匹配的行。

    3.6、possible_keys

顯示可能應用到這張表的索引,一個或者多個( 指出MySQL能使用哪個索引在該表中找到行 )

    3.7、key

實際使用的索引,若爲null,則沒有使用索引

    3.8、key_len

表示索引中使用的字節數,可通過該列計算查詢中使用的索引長度,在不損失精確型的情況下,長度越短越好,key_len顯示的值爲索引字段的最大可能長度,並非實際使用長度,即key_len是根據定義計算而得,不是通過表內檢索出的

    3.9、ref

ref顯示索引的哪一列被使用了,如果可能的話,是一個常數,哪些列或者常量被用於查找索引列上的值。
只有當type爲ref的時候,ref這列纔會有值

    3.10、rows

rows根據表統計信息以及索引選用情況,大致估算出找到所需的記錄所需要讀取的行數,所以越小越好。可以用來查詢sql的讀取行數( 掃描出的行數(估算)越小越好 )

    3.11、filtered

使用explain extended時會出現這個列,5.7之後的版本默認就有這個字段,不需要使用explain extended了。這個字段表示存儲引擎返回的數據在server層過濾後,剩下多少滿足查詢的記錄數量的比例,注意是百分比,不是具體記錄數。

    3.12、Extra

包含不適合在其他列中顯示但十分重要的額外信息(執行情況的描述和說明)

Using filesort 說明mysql會對數據使用一個外部的索引排序,而不是按照表內的索引順序進行讀取。MySQL中無法利用索引完成的排序操作稱爲“文件排序”。
Using temporary 使用了用臨時表保存中間結果,MySQL在對查詢結果排序時使用臨時表。常見於排序order by和分組查詢group by。
Using index 表示相應的select操作中使用了覆蓋索引(Covering Index),避免訪問了表的數據行,效率不錯。如果同時出現using where,表明索引被用來執行索引鍵值的查找;如果沒有同時出現using where,表明索引用來讀取數據而非執行查找動作。
Using where 表明使用where過濾
using join buffer 使用了連接緩存
impossible where where子句的值總是false,不能用來獲取任何元組
select tables optimized away 在沒有group by子句的情況下,基於索引優化Min、max操作或者對於MyISAM存儲引擎優化count(*),不必等到執行階段再進行計算,查詢執行計劃生成的階段即完成優化。
distinct 優化distinct操作,在找到第一匹配的元組後即停止找同樣值的動作。
4. SQL執行順序
select distinct 
        <select_list>
from
    <left_table><join_type>
join <right_table> on <join_condition>
where
    <where_condition>
group by
    <group_by_list>
having
    <having_condition>
order by
    <order_by_condition>
limit <limit number>
執行順序
1、from <left_table><join_type>
2、on <join_condition>
3、<join_type> join <right_table>
4、where <where_condition>
5、group by <group_by_list>
6、having <having_condition>
7、select
8、distinct <select_list>
9、order by <order_by_condition>
10、limit <limit_number>

二、索引

1. 含義
是數據庫中用來提高性能的最常用的工具
所有mysql的列類型都可以被索引
根據存儲引擎可以定義每個表的最大索引數和最大索引長度,每種存儲引擎對每個表至少支持16個索引,總索引長度至少爲256字節
MyISAM和InnoDB存儲引擎的表默認創建的都是b+Tree索引,默認情況下,Memory存儲引擎使用使用hash索引,但也支持b+Tree索引
2. 索引的作用
是爲了增加查詢速度而對錶字段附加的一種標識。可以提高系統的性能
3. 設計索引的原則
1. 最適合索引的列是出現在where字句中的列,或連接字句中指定的列,而不是出現在select關鍵字後的選擇列表中的列
2. 使用唯一索引,考慮列中值的分佈,索引的列的基數越大,索引的效果越好。
3. 使用短索引
4. 利用最左前綴
5. 不要過度使用索引,每個額外的索引都會佔用額外的磁盤空間,降低操作的性能。
6. 對於InnoDB存儲引擎的表,記錄會默認按照一定的順序進行保存,
	如果有主鍵,就會按照主鍵順序進行保存,
	如果沒有主鍵,但是有唯一索引,那麼按照唯一索引的順序保存
	如果既沒有主鍵有沒有唯一索引,表中會自動生成一個內部列,按照這個列的順序進行保存
	InnoDB表的普通索引都會保存主鍵的鍵值,所以主鍵儘可能選擇較短的數據類型。

B+Tree索引和Hash索引
	Hash索引在使用時有些特別需要注意:
		= : 兩個值進行比較,結果是0(不相等)或者1(相等)
		<=> :像常規的=運算符功能一樣,但是不同點就是,它可以判斷null,
				如果兩個操作符都是null,會返回1,而不是null
				如果其中一個操作符是null,會返回0,而不是null
		只用於使用=或者<=>操作符的等式比較,優化器不能使用Hash索引來加速order by操作
		Hash索引把數據的索引以hash形式組織起來,因此查找某條記錄的時候,速度非常快,那是因爲hash結構,每個鍵對應一個值,
			而且是散列式分佈,所以它並不支持範圍查找和排序等功能。
	B+Tree :
		當使用>、<、>=、<=、between、!=、<>、like‘’操作符時,都可以使用
4. 索引的規約
1. 若查詢條件中不包含索引的最左列,則無法使用索引
2. 對於範圍查詢,只能利用索引的最左列
3. 對於 order by a或者group by a語句,在a上建立索引,可以避免排序
4. 對於多列索引,需要所有列排序方向一致,才能利用索引。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章