在以前的面試過程當中,問到執行計劃,有不少童鞋不知道是什麼?甚至將執行計劃與執行時間認爲是同一個概念。今天咱們就一塊兒來了解一下執行計劃究竟是什麼?有什麼用途?面試
執行計劃,簡單的來講,是SQL在數據庫中執行時的表現狀況,一般用於SQL性能分析,優化等場景。在MySQL使用 explain 關鍵字來查看SQL的執行計劃。以下所示:數據庫
1.查詢t_base_user
select * from t_base_user where name="andyqian";微信
2.查看上述語句的執行計劃
explain select * from t_base_user where name="andyqian";數據結構
執行查看上述2語句後,咱們能夠得出如下執行計劃結果性能
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | t_base_user | ALL | 1 | Using where |
上面執行計劃是什麼意思呢?有什麼參考價值呢?大數據
上面這個執行計劃給到的信息是: 這個結果經過一個簡單的語句全表掃描,共掃描1行,使用where條件在t_base_user表中篩選出的。發現該語句並無走索引,爲何是這樣的呢?別急,咱們緊接着看下一節。優化
經過上面,咱們知道了什麼是執行計劃,也看到了執行計劃究竟是什麼東西,如今咱們來具體瞭解一下,MySQL執行計劃中,每一個屬性表明的是什麼意思?spa
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|
咱們一一來介紹,並說明每一個屬性有哪些可選值,以及每一個可選值的意思。.net
id
表示查詢中select操做表的順序,按順序從大到依次執行設計
select_type :
該表示選擇的類型,可選值有: SIMPLE(簡單的),
type :
該屬性表示訪問類型,有不少種訪問類型。
最多見的其中包括如下幾種: ALL(全表掃描), index(索引掃描),range(範圍掃描),ref (非惟一索引掃描),eq_ref(惟一索引掃描,),(const)常數引用, 訪問速度依次由慢到快。
其中 : range(範圍)常見與 between and ..., 大於 and 小於這種狀況。
提示 : 慢SQL是否走索引,走了什麼索引,也就能夠經過該屬性查看了。
table :
表示該語句查詢的表
possible_keys :
顧名思義,該屬性給出了,該查詢語句,可能走的索引,(如某些字段上索引的名字)這裏提供的只是參考,而不是實際走的索引,也就致使會有possible_Keys不爲null,key爲空的現象。
key : 顯示MySQL實際使用的索引,其中就包括主鍵索引(PRIMARY),或者自建索引的名字。
key_len : 表示索引所使用的字節數,
ref :
鏈接匹配條件,若是走主鍵索引的話,該值爲: const, 全表掃描的話,爲null值
rows :
掃描行數,也就是說,須要掃描多少行,採能獲取目標行數,通常狀況下會大於返回行數。一般狀況下,rows越小,效率越高, 也就有大部分SQL優化,都是在減小這個值的大小。
注意: 理想狀況下掃描的行數與實際返回行數理論上是一致的,但這種狀況及其少,如關聯查詢,掃描的行數就會比返回行數大大增長)
Extra 這個屬性很是重要,該屬性中包括執行SQL時的真實狀況信息,如上面所屬,使用到的是"using where",表示使用where篩選獲得的值,經常使用的有: "Using temporary": 使用臨時表 "using filesort": 使用文件排序
看到這裏,咱們應該已經發現,在第一步中,咱們的這條SQL
select * from t_base_user where name="andyqian";
是沒有走索引的,並且仍是全表掃描,在數據量少的狀況下,問題還不會特別突出,若是數據量比較大,這但是個會形成生產事故的慢查詢哦,如今咱們改造一下,將name字段添加上索引,
添加索引
alter table t_base_user add index idx_name(name);
看看它的執行計劃是怎樣的。
id | select_type | table | type | possible_kes | key | key_len | ref | rows | Extra |
---|---|---|---|---|---|---|---|---|---|
1 | SIMPLE | t_base_user | ref | idx_name | idx_name | 93 | cons | 1 | Using where |
你看,如今已經走idx_name索引了,其type從All(全表掃描)到ref(非惟一索引了),別看就只有這一點點小區別,在大數據量的時候,但是會起大做用的哦。
本文中演示的數據結構以下:
create table t_base_user(
oid bigint(20) not null primary key auto_increment,
name varchar(30) null comment "name",
email varchar(30) null comment "email",
age int null comment "age",
telephone varchar(30) null comment "telephone",
status tinyint(4) null comment "0 無效 1 有效",
created_at datetime null comment "",
updated_at datetime null comment ""
)
// 新增記錄:
insert into t_base_user (name,email,age,telephone,created_at,updated_at) values ("andyqian","andytohome",20,"15608411",now(),now();)
一個好的數據庫表設計,從一開始就應該考慮添加索引,而不是到最後發現慢SQL了,影響業務了,纔來補救。其實我在工做經歷當中,因爲新建表,或新加字段後,忘記添加索引也形成了屢次生產事故,記憶猶新!!! 其實新建索引也是有必定的原則的,建什麼索引,建在哪些字段上,這裏面還有很多知識呢,下一篇文章寫,盡請期待吧!
掃碼關注,一塊兒進步
我的博客: http://www.andyqian.com