索引是什么?
MySQL官方對(duì)索引的定義為:索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu);
索引是提高查詢速度的最重要的工具,雖然還有一些其他技術(shù)能提升性能,但一般來(lái)說(shuō)引起最大性能差異的,都是索引的正確使用,所以應(yīng)該首先從索引的角度來(lái)提升性能;
MySQL索引類型
普通索引(INDEX),最基本的索引,沒(méi)有任何限制;
唯一索引(UNIQUE),值必須是唯一,但允許空;
主鍵索引(PRIMARY KEY),是一種特殊的唯一索引,不允許有空值;
全文索引(FULLTEXT),僅可用于MyISAM,檢索文本信息用,針對(duì)較大的數(shù)據(jù),生成時(shí)耗時(shí)耗空間;
單列索引:一個(gè)索引只包含一個(gè)列,注意,多個(gè)單列索引之間沒(méi)有任何關(guān)系;
多列索引(組合索引):一個(gè)索引包含多各列,尤其需要注意的是創(chuàng)建組合索引時(shí)各列的順序;
MySQL索引方法——BTree
BTree索引:MySQL數(shù)據(jù)庫(kù)中使用最頻繁的索引類型,基本所有存儲(chǔ)引擎都支持BTree索引,下圖分別是MyISAM和InnoDB存儲(chǔ)引擎的BTree索引。
MySQL索引方法——Hash
Hash索引:主要通過(guò)Hash算法(常見(jiàn)的Hash算法有直接定址法、平方取中法、折疊法、除數(shù)取余法、隨機(jī)數(shù)法),將數(shù)據(jù)庫(kù)字段數(shù)據(jù)轉(zhuǎn)換成定長(zhǎng)的Hash值,與這條數(shù)據(jù)的行指針一并存入Hash表的對(duì)應(yīng)位置;如果發(fā)生Hash碰撞(兩個(gè)不同關(guān)鍵字的Hash值相同),則在對(duì)應(yīng)Hash鍵下以鏈表形式存儲(chǔ)。
檢索算法:在檢索查詢時(shí),就再次對(duì)待查關(guān)鍵字再次執(zhí)行相同的Hash算法,得到Hash值,到對(duì)應(yīng)Hash表對(duì)應(yīng)位置取出數(shù)據(jù)即可,如果發(fā)生Hash碰撞,則需要在取值時(shí)進(jìn)行篩選。目前使用Hash索引的數(shù)據(jù)庫(kù)并不多,主要有Memory等。
一般來(lái)說(shuō),索引的檢索效率非常高,可以一次定位,不像B-Tree索引需要進(jìn)行從根節(jié)點(diǎn)到葉節(jié)點(diǎn)的多次IO操作。有利必有弊,Hash算法在索引的應(yīng)用也有很多弊端,例如:
a、Hash索引僅僅能滿足等值的查詢,范圍查詢不保證結(jié)果正確。因?yàn)閿?shù)據(jù)在經(jīng)過(guò)Hash算法后,其大小關(guān)系就可能發(fā)生變化。
b、Hash索引不能被排序。同樣是因?yàn)閿?shù)據(jù)經(jīng)過(guò)Hash算法后,大小關(guān)系就可能發(fā)生變化,排序是沒(méi)有意義的。
c、Hash索引不能避免表數(shù)據(jù)的掃描。因?yàn)榘l(fā)生Hash碰撞時(shí),僅僅比較Hash值是不夠的,需要比較實(shí)際的值以判定是否符合要求。
d、Hash索引在發(fā)生大量Hash值相同的情況時(shí)性能不一定比B-Tree索引高。因?yàn)榕鲎睬闆r會(huì)導(dǎo)致多次的表數(shù)據(jù)的掃描,造成整體性能的低下,可以通過(guò)采用合適的Hash算法一定程度解決這個(gè)問(wèn)題。
e、Hash索引不能使用部分索引鍵查詢。因?yàn)楫?dāng)使用組合索引情況時(shí),是把多個(gè)數(shù)據(jù)庫(kù)列數(shù)據(jù)合并后再計(jì)算Hash值,所以對(duì)單獨(dú)列數(shù)據(jù)計(jì)算Hash值是沒(méi)有意義的。
索引的優(yōu)缺點(diǎn)
索引的優(yōu)點(diǎn)是可以提高檢索數(shù)據(jù)的速度,這是創(chuàng)建索引的最主要的原因;對(duì)于有依賴關(guān)系的子表和父表之間的聯(lián)合查詢時(shí),可以顯著提高查詢速度;使用分組和排序子句進(jìn)行數(shù)據(jù)查詢時(shí),同樣可以顯著節(jié)省查詢中分組和排序的時(shí)間。
索引的缺點(diǎn)是創(chuàng)建和維護(hù)索引需要耗費(fèi)時(shí)間,耗費(fèi)時(shí)間的數(shù)量隨著數(shù)據(jù)量的增加而增加;每一個(gè)索引要占一定的物理空間;增加、刪除和修改數(shù)據(jù)時(shí),要?jiǎng)討B(tài)的維護(hù)索引,造成數(shù)據(jù)的維護(hù)速度降低了。
各種索引的適用場(chǎng)景
索引的本質(zhì):以空間換時(shí)間,以插入更新速度降低換取查詢檢索速度的提升。
主鍵索引/唯一索引:以更快的速度精準(zhǔn)的定位到某條數(shù)數(shù)據(jù),適用于絕大多數(shù)需要更新和查詢的表(只會(huì)插入數(shù)據(jù)的表除外),絕對(duì)用不到范圍查詢的可以使用Hash索引;
普通索引/組合索引:表的關(guān)聯(lián)、查詢,適用于查詢需求較多的表,對(duì)經(jīng)常插入和更新的表要適當(dāng)降低組合索引的使用;
全文索引:全文檢索使用,但如果有的選擇,盡量不用數(shù)據(jù)庫(kù)自己的全文索引。
Hash索引:主鍵,MD5碼等需要唯一確定一條數(shù)據(jù)的等值查詢,需要范圍查詢的不能使用Hash索引;