SQL優化 MySQL版 -分析explain SQL執行計劃與Type級別詳解

type索引類型、類型

做者 : Stanley 羅昊html

轉載請註明出處和署名,謝謝!

注:看此文章前,須要有必定的Mysql基礎或觀看上一篇文章,該文章傳送門:算法

https://www.cnblogs.com/StanleyBlogs/p/10416865.html

索引類型type

咱們能夠清楚的看到type那一欄有index ALL eq_ref,他們都表明什麼意思呢?sql

首先類型有許多,這裏我只給你們介紹企業裏面用的最多的類型:數據庫

system>const>eq_ref>ref>range>index>ALL性能

越往左邊,性能越高好比system就比ALL類型性能要高出許多,其中system、const只是理想類型,基本達不到;優化

咱們本身實際能優化到ref>range這兩個類型,就是你本身寫SQL,若是你沒優化基本上就是ALL,若是你優化了,那就儘可能達到ref>range這兩個級別;spa

這裏我強調一下,左邊基本達不到!code

因此,要對type優化的前提是,你須要有索引,若是你連索引都沒有建立,那你就不用優化了,確定是ALL.....orm

Type級別詳解

一.system級別

索引類型能是system的只有兩種狀況:htm

1.只有一條數據的系統表

只有一條數據的系統表,就是系統裏自帶一張表,而且這個表就一條數據,這個基本上就達不到,這個是系統自帶的表,並且就一條數據,因此基本達不到;

2.或衍生表只能有一條數據的主查詢

這個是能夠實現的,可是在實際開發當中,你不可能去寫一個這麼個玩意兒,不可能公司的業務去讓你把SQL索引類型寫實system...

SQL語句:select * From (select * From test01) t where tid = 1;//前面須要加explain

執行結果:

就是把它湊出來便可;

我之因此能達到system,是由於我知足了它的第二個條件;

二.const級別

const條件稍微低一點,可是基本上也達不到;

1.僅僅能查出一條的SQL語句而且用於Primary key 或 unique索引;

這個我就不說了把,都知道,因此在企業里根本不可能實現,能查出來一條SQL語句,你的索引還必須是Primary key或unique;

可是咱們能夠把它湊出來,我再強調一點,在公司,大家的業務不可能去讓你湊type級別!

SQL語句:select * tid From test01 where tid = 1;//前面須要加explain

執行結果:

根據tid找,由於tid是我設置的主鍵,主鍵就是Primary key,而且只能有一條數據,我表裏面原本就一條,因此我知足了;

三.eq_ref級別

惟一性索引:對於每一個索引鍵的查詢,返回匹配惟一行數據(有且只有1個,不能多,不能0);

解說:好比你select ...from 一張表 where 比方說有一個字段 name = 一個東西,也就是咱們以name做爲索引,假設我以前給name加了一個索引值,我如今根據name去查,查完後有20條數據,我就必須保證這二十條數據每行都是惟一的,不能重複不能爲空!

只要知足以上條件,你就能達到eq_ref,固然前提是你要給name建索引,若是name連索引都沒,那你確定達不到eq_ref;

此種狀況常見於惟一索引和主鍵索引;

好比我根據name去查,可是一個公司裏面或一個學校裏面叫name的可能不止一個,通常你想用這個的時候,就要確保你這個字段是惟一的,id就能夠,你能夠重複兩個張三,可是你身份證確定不會重複;

添加惟一鍵語法:alter table 表名 add constraint 索引名 unique index(列名)

檢查字段是否惟一鍵:show index form 表名;被展現出來的皆是有惟一約束的;

以上級別,均是可遇不可求!!!!

四 .ref級別

到ref仍是問題不大的,只要你上點心,就能夠達到

非惟一性索引:對於每一個索引鍵的查詢,返回匹配的全部行(能夠是0,或多個)

假設我如今要根據name查詢,首先name可能有多個,由於一個公司或學校叫小明的不止一我的,可是你要用name去查,你必須name是索引,咱們先給它加個索引,由於要達到ref級別,因此這裏我給它加一個單值索引,關於單值索引的介紹我在前幾篇文章講過:

傳送門:

https://www.cnblogs.com/StanleyBlogs/p/10416865.html

單值索引語法:alter table 表名 索引類型 索引名(字段)

如今咱們根據索引來查數據,這裏我假設我寫的單值索引;

alter table student add index index_name (name);

這個時候咱們再去編寫sql語句:

alter table student add index index_name (name);

由於name是索引列,這裏假設有兩個叫張三的,ref級別規則就是能查出多個或0個,很顯然能查出來多個,那這條SQL語句,必然是ref級別!

執行結果:

數據:

五.range級別

檢索指定範圍的行,查找一個範圍內的數據,where後面是一個範圍查詢 (between,in,> < >=);

注:in 有時會失效,致使爲ALL;

如今咱們寫一個查詢語句,前提是,tid必定是一個索引列,若是是id的話,就用主鍵索引,也就是惟一索引,值不能夠重複,這個時候咱們範圍查詢的時候要用它來作條件:

 EXPLAIN SELECT t.* FROM student t WHERE t.tid BETWEEN 1 AND 2; ;//查詢tid是1到2;

查看執行結果:

我表示,我在這試了好幾回都是index級別,我也不知道爲何,我即使知足條件還是index級別,多是數據庫版本?若是你知道的話,請務必在下發留言與我交流!

六.index級別

查詢所有索引中的數據

講解:假設我有一張表,裏面有id name age,這個時候name是一個單值索引,一旦name被設定成索引,它就會成爲B樹同樣,通過各類算法將name裏面的值像樹同樣進行分類,這個時候我where name = **,就至關於把這顆B樹查了一個遍,

也就是說,你把name這一列給查了一遍;

SQL語句:select id From student;//我只查被索引聲明的列,必然就是index了;

執行結果:

七.ALL級別

查詢所有表數據,就是select name From student;

其中 name 不是索引;

若是你查的這一列不是索引,就會致使全表掃描,因此要避免全表掃描

執行結果:

今日感悟:

靠本身獲得的,是榮譽,

   乞求父母獲得的,是虛榮

相關文章
相關標籤/搜索