MySQL優化常見Extra分析——慢查詢優化


數據准備:

create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engine=innodb;

數據說明:
用戶表:id主鍵索引,name普通索引(非唯一),sex無索引;
四行記錄:其中name普通索引存在重復記錄lisi;

一、【Using where】

實驗語句:
explain select * from user where sex='no';

結果說明:
Extra為Using where說明,SQL使用了where條件過濾數據。

需要注意的是:
(1)返回所有記錄的SQL,不使用where條件過濾數據,大概率不符合預期,對於這類SQL往往需要進行優化;
(2)使用了where條件的SQL,並不代表不需要優化,往往需要配合explain結果中的type(連接類型)來綜合判斷;

本例雖然Extra字段說明使用了where條件過濾,但type屬性是ALL,表示需要掃描全部數據,仍有優化空間。

常見的優化方法為,在where過濾屬性上添加索引。

畫外音:本例中,sex字段區分度不高,添加索引對性能提升有限。

二、【Using index】

實驗語句:
explain select id,name from user where name='shenjian';

結果說明:
Extra為Using index說明,SQL所需要返回的所有列數據均在一棵索引樹上,而無需訪問實際的行記錄。

這類SQL語句往往性能較好。

問題來了,什么樣的列數據,會包含在索引樹上呢?

三、【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呢?

四、【Using filesort】

實驗語句:
explain select * from user order by sex;

結果說明:
Extra為Using filesort說明,得到所需結果集,需要對所有記錄進行文件排序。

這類SQL語句性能極差,需要進行優化。

典型的,在一個沒有建立索引的列上進行了order by,就會觸發filesort,常見的優化方案是,在order by的列上添加索引,避免每次查詢都全量排序。

五、【Using temporary】

實驗語句:
explain select * from user group by name order by sex;

結果說明:
Extra為Using temporary說明,需要建立臨時表(temporary table)來暫存中間結果。

這類SQL語句性能較低,往往也需要進行優化。

典型的,group by和order by同時存在,且作用於不同的字段時,就會建立臨時表,以便計算出最終的結果集。

六、【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也就基本搞定了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM