索引類型type

我們可以清楚的看到type那一欄有index ALL eq_ref,他們都代表什么意思呢?
首先類型有許多,這里我只給大家介紹企業里面用的最多的類型:
system>const>eq_ref>ref>range>index>ALL
越往左邊,性能越高,比如system就比ALL類型性能要高出許多,其中system、const只是理想類型,基本達不到;
我們自己實際能優化到ref>range這兩個類型,就是你自己寫SQL,如果你沒優化基本上就是ALL,如果你優化了,那就盡量達到ref>range這兩個級別;
這里我強調一下,左邊基本達不到!
所以,要對type優化的前提是,你需要有索引,如果你連索引都沒有創建,那你就不用優化了,肯定是ALL.....;
Type級別詳解
一.system級別
索引類型能是system的只有兩種情況:
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 不是索引;
如果你查的這一列不是索引,就會導致全表掃描,所以要避免全表掃描;
執行結果:

今日感悟:
靠自己得到的,是榮譽,
乞求父母得到的,是虛榮
