本文主要總結了一下MySql索引的基礎知識和常見的索引娄帖。比較簡潔,可能會有些晦澀昙楚。不明白的地方近速,可以參考以下幾篇博客學習。
參考博客 :
MySql數據庫索引原理
Mysql學習-索引總結
B-Tree百度百科
一堪旧、為什么使用索引
當數據量較大的時候削葱,如果不適用索引,則對整表掃描淳梦,效率較低析砸。如果創(chuàng)建了索引,則根據算法優(yōu)化排序指定列爆袍,能快速定位到數據的地址首繁,提高查詢速度。
二陨囊、索引列數據類型的選擇
不同數據類型在創(chuàng)建索引時弦疮,磁盤、CPU蜘醋、內存開銷不同胁塞,應選擇較為合適類型
- 越小的類型越好。占用字節(jié)少的類型在計算堂湖、存儲等過程中更為迅速闲先。
- 簡單數據類型更好。簡單數據類型的比較要比字符串比較的性能高得多无蜂。用MySql的時間類型存儲時間而不是字符串伺糠。用整型存儲IP(這個不太理解)。
- 盡量避免null斥季。MySql中含有空值的列很難進行查詢優(yōu)化训桶,應用0或者其他字符代替null。
三酣倾、索引類型
索引是在存儲引擎實現的舵揭,而不是服務層。不同的存儲引擎所支持的索引也不一樣躁锡。
1.B-Tree索引
-
索引原理
B-Tree索引午绳,將索引列數據組成一個m階h層B-Tree,每個非葉子節(jié)點存放m/2-m個數據以及對應子節(jié)點的指針映之,且這些數據都在一塊磁盤塊里拦焚。在查找時蜡坊,將根節(jié)點讀進內存,IO次數+1赎败,進行二分查找秕衙,二分查找為內存處理,時間忽略不計僵刮;然后查找對應的子節(jié)點据忘,將子節(jié)點的數據讀進內存,IO次數+1搞糕。所以最差的搜索時間是h次IO勇吊。一般B-Tree只有2-4層,也就是只有2-4次IO窍仰,而沒有索引時需要每一條數據讀一次IO萧福,非常消耗時間。
簡言之辈赋,普通查詢需要逐行匹配數據,IO次數較多膏燕,效率很低钥屈。于是將經常查詢的列創(chuàng)建B-Tree類型的索引,根據B-Tree的特性坝辫,大大降低IO次數篷就,達到提高性能的目的。
B-tree索引適用于全值匹配近忙、匹配最左前綴竭业、匹配列前綴、匹配范圍值
-
效率
最低效率為全局二分查找的結果
原則
當明白了B-Tree索引的原理之后及舍,我們就可以根據他的原理未辆,正確的使用它。
a.最左前綴原則
復合索引虛滿足最左前綴原則锯玛。即所以在查詢是從最左邊列開始匹配咐柜,匹配到范圍查詢時停止。如(a,b,c,d)
復合索引攘残,如果查詢時不提供a
列拙友,無法查詢;如果b
列為like,>,<,between
歼郭,則c,d
列條件無效遗契。另=和in
可以亂序,MySql的優(yōu)化器會將其優(yōu)化為正確順序病曾。
復合索引牍蜂,即多列組成的索引(我理解他們是把多列綁定在一起)漾根,如果你左邊的列都不提供,怎么能匹配后續(xù)列呢捷兰?
b.盡量選擇字段較小立叛、區(qū)分度高的列做索引
由B-Tree的原理我們可以知道,B-Tree的性能很大部分依賴于樹的高度h贡茅,而h=log(m+1)N秘蛇,也就是每個磁盤塊的數據項的個數越多,h越小顶考,性能越高赁还。磁盤塊的大小是固定的,則數據項的大小越小驹沿,m越大艘策,h越小,性能越好渊季。所以要選擇盡量小的數據列
區(qū)分度高是為了更好的篩選數據朋蔫。
c.索引不能參與計算
索引列不能參與計算,保持列“干凈”却汉,比如from_unixtime(create_time) = ’2014-05-29’
就不能使用到索引驯妄。B-Tree中存儲的都是數據表中的值,如果進行計算以后再匹配的話合砂,需要把所有結果都進行運算以后才能檢索青扔,檢索成本增加。
索引的目的就是當我們檢索某些數據的時候通過檢索索引列提高效率翩伪。如果把索引列的數據進行計算以后再進行檢索微猖,那就索引列的意義就不在了。
d.盡量擴展索引缘屹,不要新建索引
2.Hash索引
Hash索引只在Memory存儲引擎中顯示支持
顧名思義凛剥,Hash索引時對相應列的hash值進行存儲,那么它就包含了一些hash的特性轻姿。
- a. 索引中不存儲數據
索引中存儲的都是對應列的hash值当悔,只能定位到對應數據的位置進行讀取。
- b. 不能進行排序
- c. 不能進行部分字段匹配
- d. 只能進行等值匹配踢代,不能進行范圍匹配
- e. 匹配速度較快
3.其他索引
Mysql常見的索引:普通索引盲憎、主鍵索引、唯一索引胳挎、組合索引饼疙、全文索引
主鍵索引
一種特殊的唯一索引,且不允許有空值
唯一索引
列的值唯一,可以為空窑眯。如果是組合索引屏积,多列組成的值必須唯一。
組合索引
多列組合創(chuàng)建的索引磅甩,主要為了滿足平時SQL中的一些組合查詢條件
全文索引
全文索引時可以支持字符內搜索的索引炊林。如實現like '%hello%'
的功能。同時它還支持自然語言搜索和布爾搜索卷要。
注:當數據量較大的時候渣聚,生成全局索引會很耗時、耗空間僧叉。具體使用的時候再進行詳細的調研奕枝。
自然語言搜索
自然語言索引引擎將計算每一個文檔對象和查詢的相關度。這里瓶堕,相關度是指基于匹配的關鍵詞個數隘道,以及關鍵詞在文檔中出現的個數。
自然語言索引是默認的郎笆。
如match()
方法等布爾搜索
布爾搜索其實是采用一些計算符來進行篩選然后搜索谭梗。
+word
:表示word必須存在
-word
:表示word必須不存在
(no operator)
表示word是可選的。但是如果是可選的宛蚓,其相關性會更高
select *from fts where match(body) against("+django -python" IN BOOLEANMODE);
>
表示出現該word增加相關性
<
表示出現該word降低相關性
select *,match(body) against("flask >python <django" in boolean mode) as rf from fts;
@distance
表示查詢的多個單詞之間的距離是否在distance之內
select *from fts where match(body) against('"django flask"@3' IN BOOLEANMODE)
~
允許出現該單詞默辨,但是出現時相關性為負
*
表示以該單詞開頭的單詞,如lik*苍息,表示可以是like,likes和lik
select *from fts where match(body) against("p*" IN BOOLEAN MODE);
“
表示短語
select *from fts where match(body) against('"hello world"'IN BOOLEAN MODE);