做者 : Stanley 羅昊html
注:看此文章前,須要有必定的Mysql基礎或觀看上一篇文章,該文章傳送門:算法
https://www.cnblogs.com/StanleyBlogs/p/10416865.html
咱們能夠清楚的看到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
索引類型能是system的只有兩種狀況:htm
1.只有一條數據的系統表
只有一條數據的系統表,就是系統裏自帶一張表,而且這個表就一條數據,這個基本上就達不到,這個是系統自帶的表,並且就一條數據,因此基本達不到;
2.或衍生表只能有一條數據的主查詢
這個是能夠實現的,可是在實際開發當中,你不可能去寫一個這麼個玩意兒,不可能公司的業務去讓你把SQL索引類型寫實system...
SQL語句:select * From (select * From test01) t where tid = 1;//前面須要加explain
執行結果:
就是把它湊出來便可;
我之因此能達到system,是由於我知足了它的第二個條件;
const條件稍微低一點,可是基本上也達不到;
1.僅僅能查出一條的SQL語句而且用於Primary key 或 unique索引;
這個我就不說了把,都知道,因此在企業里根本不可能實現,能查出來一條SQL語句,你的索引還必須是Primary key或unique;
可是咱們能夠把它湊出來,我再強調一點,在公司,大家的業務不可能去讓你湊type級別!
SQL語句:select * tid From test01 where tid = 1;//前面須要加explain
執行結果:
根據tid找,由於tid是我設置的主鍵,主鍵就是Primary key,而且只能有一條數據,我表裏面原本就一條,因此我知足了;
惟一性索引:對於每一個索引鍵的查詢,返回匹配惟一行數據(有且只有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仍是問題不大的,只要你上點心,就能夠達到;
非惟一性索引:對於每一個索引鍵的查詢,返回匹配的全部行(能夠是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級別!
執行結果:
數據:
檢索指定範圍的行,查找一個範圍內的數據,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級別,多是數據庫版本?若是你知道的話,請務必在下發留言與我交流!
查詢所有索引中的數據
講解:假設我有一張表,裏面有id name age,這個時候name是一個單值索引,一旦name被設定成索引,它就會成爲B樹同樣,通過各類算法將name裏面的值像樹同樣進行分類,這個時候我where name = **,就至關於把這顆B樹查了一個遍,
也就是說,你把name這一列給查了一遍;
SQL語句:select id From student;//我只查被索引聲明的列,必然就是index了;
執行結果:
查詢所有表數據,就是select name From student;
其中 name 不是索引;
若是你查的這一列不是索引,就會致使全表掃描,因此要避免全表掃描;
執行結果:
今日感悟:
靠本身獲得的,是榮譽,
乞求父母獲得的,是虛榮