數據準備:工具
create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engine=innodb;
數聽說明:
用戶表:id主鍵索引,name普通索引(非惟一),sex無索引;
四行記錄:其中name普通索引存在重複記錄lisi;
oop
1、【Using where】
實驗語句:
explain select * from user where sex='no';性能
結果說明:
Extra爲Using where說明,SQL使用了where條件過濾數據。優化
須要注意的是:
(1)返回全部記錄的SQL,不使用where條件過濾數據,大機率不符合預期,對於這類SQL每每須要進行優化;
(2)使用了where條件的SQL,並不表明不須要優化,每每須要配合explain結果中的type(鏈接類型)來綜合判斷;spa
本例雖然Extra字段說明使用了where條件過濾,但type屬性是ALL,表示須要掃描所有數據,仍有優化空間。code
常見的優化方法爲,在where過濾屬性上添加索引。blog
畫外音:本例中,sex字段區分度不高,添加索引對性能提高有限。排序
2、【Using index】
實驗語句:
explain select id,name from user where name='shenjian';索引
結果說明:
Extra爲Using index說明,SQL所須要返回的全部列數據均在一棵索引樹上,而無需訪問實際的行記錄。it
這類SQL語句每每性能較好。
問題來了,什麼樣的列數據,會包含在索引樹上呢?
3、【Using index condition】
實驗語句:
explain select id,name,sex from user
where name='shenjian';
畫外音:該SQL語句與上一個SQL語句不一樣的地方在於,被查詢的列,多了一個sex字段。
結果說明:
Extra爲Using index condition說明,確實命中了索引,但不是全部的列數據都在索引樹上,還須要訪問實際的行記錄。
這類SQL語句性能也較高,但不如Using index。
問題來了,如何優化爲Using index呢?
4、【Using filesort】
實驗語句:
explain select * from user order by sex;
結果說明:
Extra爲Using filesort說明,獲得所需結果集,須要對全部記錄進行文件排序。
這類SQL語句性能極差,須要進行優化。
典型的,在一個沒有創建索引的列上進行了order by,就會觸發filesort,常見的優化方案是,在order by的列上添加索引,避免每次查詢都全量排序。
5、【Using temporary】
實驗語句:
explain select * from user group by name order by sex;
結果說明:
Extra爲Using temporary說明,須要創建臨時表(temporary table)來暫存中間結果。
這類SQL語句性能較低,每每也須要進行優化。
典型的,group by和order by同時存在,且做用於不一樣的字段時,就會創建臨時表,以便計算出最終的結果集。
6、【Using join buffer (Block Nested Loop)】
實驗語句:
explain select * from user where id in (select id from user where sex='no');
結果說明:
Extra爲Using join buffer (Block Nested Loop)說明,須要進行嵌套循環計算。
畫外音:內層和外層的type均爲ALL,rows均爲4,須要循環進行4*4次計算。
這類SQL語句性能每每也較低,須要進行優化。
典型的,兩個關聯表join,關聯字段均未創建索引,就會出現這種狀況。常見的優化方案是,在關聯字段上添加索引,避免每次嵌套循環計算。
結尾:
explain是SQL優化中最經常使用的工具,搞定type和Extra,explain也就基本搞定了。