《兩個工具分析SQL死鎖》
《SQL空值帶來的大坑》
兩個案例分析,展示了MySQL性能分析工具explain的強大。數據庫
《同一個SQL語句,爲啥性能差別咋就這麼大呢?》
詳細敘述了explain結果中最重要的type字段(鏈接類型)的含義。架構
其實,explain結果中還有一個Extra字段,對分析與優化SQL有很大的幫助,今天花1分鐘簡單和你們聊一聊。ide
create table user ( id int primary key, name varchar(20), sex varchar(5), index(name) )engine=innodb;
insert into user values(1, 'shenjian','no'); insert into user values(2, 'zhangsan','no'); insert into user values(3, 'lisi', 'yes'); insert into user values(4, 'lisi', 'no');
用戶表:id主鍵索引,name普通索引(非惟一),sex無索引;
四行記錄:其中name普通索引存在重複記錄lisi;工具
經過構造各種SQL語句,對explain的Extra字段進行說明,啓發式定位待優化低性能SQL語句。oop
explain select * from user where sex='no';
Extra爲Using where說明,SQL使用了where條件過濾數據。
須要注意的是:
(1)返回全部記錄的SQL,不使用where條件過濾數據,大機率不符合預期,對於這類SQL每每須要進行優化;
(2)使用了where條件的SQL,並不表明不須要優化,每每須要配合explain結果中的type(鏈接類型)來綜合判斷;
畫外音:join type在《同一個SQL語句,爲啥性能差別咋就這麼大呢?》一文中有詳細敘述,本文再也不展開。性能
本例雖然Extra字段說明使用了where條件過濾,但type屬性是ALL,表示須要掃描所有數據,仍有優化空間。優化
常見的優化方法爲,在where過濾屬性上添加索引。
畫外音:本例中,sex字段區分度不高,添加索引對性能提高有限。code
explain select id,name from user where name='shenjian';
Extra爲Using index說明,SQL所須要返回的全部列數據均在一棵索引樹上,而無需訪問實際的行記錄。
畫外音:The column information is retrieved from the table using only information in the index tree without having to do an additional seek to read the actual row.orm
這類SQL語句每每性能較好。blog
實驗語句:
explain select id,name,sex from user where name='shenjian';
畫外音:該SQL語句與上一個SQL語句不一樣的地方在於,被查詢的列,多了一個sex字段。
結果說明:
Extra爲Using index condition說明,確實命中了索引,但不是全部的列數據都在索引樹上,還須要訪問實際的行記錄。
畫外音:彙集索引,普通索引的底層實現差別,詳見《1分鐘瞭解MyISAM與InnoDB的索引差別》。
這類SQL語句性能也較高,但不如Using index。
explain select * from user order by sex;
Extra爲Using filesort說明,獲得所需結果集,須要對全部記錄進行文件排序。
這類SQL語句性能極差,須要進行優化。
典型的,在一個沒有創建索引的列上進行了order by,就會觸發filesort,常見的優化方案是,在order by的列上添加索引,避免每次查詢都全量排序。
實驗語句:
explain select * from user group by name order by sex;
結果說明:
Extra爲Using temporary說明,須要創建臨時表(temporary table)來暫存中間結果。
這類SQL語句性能較低,每每也須要進行優化。
典型的,group by和order by同時存在,且做用於不一樣的字段時,就會創建臨時表,以便計算出最終的結果集。
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也就基本搞定了。
架構師之路-分享技術思路
相關推薦:
《緩衝池(buffer pool),此次完全懂了!》
《寫緩衝(change buffer),此次完全懂了!》
做業:
select id,name where XXX是Using index;
select id,name,sex where XXX是Using index condition;
後者如何優化爲Using index呢?
但願你們有收穫,幫忙再看喲。