索引類型一般分為聚簇索引和非聚簇索引(聯(lián)合索引、唯一索引墓捻、前綴索引等),這篇文章主要說(shuō)的是聚簇索引坊夫。
聚簇索引是一種數(shù)據(jù)庫(kù)索引類型結(jié)構(gòu)砖第,它實(shí)質(zhì)上是一顆B+Tree,按照聚簇索引的鍵值進(jìn)行順序排序环凿。
聚簇索引和非聚簇索引的區(qū)別
聚簇索引:
- 使用的B+Tree創(chuàng)建索引梧兼,葉子節(jié)點(diǎn)直接保存的對(duì)應(yīng)每一行的數(shù)據(jù),由于數(shù)據(jù)和索引是在一起的智听,并且數(shù)據(jù)一旦儲(chǔ)存羽杰,順序只有一種,所以一個(gè)表只能有一個(gè)聚簇索引瞭稼。
- 聚簇索引是在存儲(chǔ)引擎的基礎(chǔ)上有的概念忽洛,所以不是所有的存儲(chǔ)引擎都會(huì)有聚簇索引的,下面我們都是以InnoDB為例环肘。
- 當(dāng)InnoDB創(chuàng)建主鍵時(shí)欲虚,會(huì)默認(rèn)幫主鍵創(chuàng)建聚簇索引,又稱主鍵索引悔雹。如果沒(méi)有創(chuàng)建主鍵時(shí)复哆,會(huì)優(yōu)先選擇表中第一個(gè)NOT NULL的唯一索引當(dāng)作聚簇索引,如果以上均沒(méi)有InnoDB存儲(chǔ)引擎會(huì)默認(rèn)增加一個(gè)隱藏的字節(jié)數(shù)為6的字段ROW-ID作為聚簇索引腌零。
在InnoDB中梯找,聚簇索引的實(shí)例圖:
InnoDB的聚簇索引
在InnoDB的聚簇索引中,葉子節(jié)點(diǎn)保存了索引鍵值和行數(shù)據(jù)益涧,他們是以索引的鍵值順序排列成一個(gè)鏈表锈锤,這樣也非常適用于范圍查找。
ps:MyISAM沒(méi)有聚簇索引。
非聚簇索引:
- 使用的B+Tree樹(shù)創(chuàng)建索引久免。
- 非聚簇索引也稱為二級(jí)索引浅辙,MyISAM表沒(méi)有聚簇索引,只有二級(jí)索引阎姥,在MyISAM中记舆,單個(gè)或多個(gè)二級(jí)索引的葉子節(jié)點(diǎn)存放的都是數(shù)據(jù)行的引用地址。InnoDB表中呼巴,二級(jí)索引的葉子節(jié)點(diǎn)存放的是索引值和聚簇索引的ID值泽腮。
在MyISAM中,非聚簇索引的實(shí)例圖:
MyISAM非聚簇索引
在MyISAM中衣赶,所有的非聚簇索引葉子節(jié)點(diǎn)中存放的都是數(shù)據(jù)引用的地址诊赊,所以索引占用空間相對(duì)比較小,所以搜索速度比較快屑埋。
在InnoDB中豪筝,非聚簇索引的實(shí)例圖:
InnoDB非聚簇索引
在InnoDB中,非聚簇索引的葉子節(jié)點(diǎn)保存的是索引值和聚簇索引的值摘能,當(dāng)查詢到聚簇索引值時(shí),再需要從聚簇索引中查找的對(duì)應(yīng)的行敲街,需要進(jìn)行二次查找团搞,如果聚簇索引的值設(shè)置的比較大,那么索引占用的空間就比較大多艇,這也是為什么MyISAM普遍要比InnoDB查詢速度快的原因逻恐。
聚簇索引的優(yōu)點(diǎn):
- 提高查詢性能:聚簇索引將行數(shù)據(jù)保存在葉子節(jié)點(diǎn)中,當(dāng)直接用聚簇索引單行查詢時(shí)峻黍,可以通過(guò)較少的I/O操作快速定位到所需的數(shù)據(jù)行并返回复隆。
- 聚合查詢:聚簇索引中的數(shù)據(jù)行是按照索引鍵值順序排序,所以可以快速排序(SORT BY)姆涩、分組(GROUP BY)挽拂、匯總等。
- 范圍查找:聚簇索引中的數(shù)據(jù)行是按照索引鍵值順序排序骨饿,所以可以根據(jù)指定的返回快速查找所需的數(shù)據(jù)行并返回亏栈。
- 索引覆蓋:由于聚簇索引中葉子節(jié)點(diǎn)保存了數(shù)據(jù)行的全部數(shù)據(jù),因此在一些情況下宏赘∪薇保可以通過(guò)聚簇索引來(lái)覆蓋查詢的所有列,避免了查詢需要回表的額外I/O操作察署,提高查詢消息闷游。(覆蓋索引會(huì)單獨(dú)出一篇)
- 減少存儲(chǔ)空間:聚簇索引將行數(shù)據(jù)保存在葉子節(jié)點(diǎn)中,所以可以不用像非聚簇索引一樣,單獨(dú)維護(hù)一份索引數(shù)據(jù)脐往。
使用聚簇索引注意的點(diǎn):
- 一般InnoDB表都會(huì)建立主鍵休吠,并設(shè)置自動(dòng)增長(zhǎng),避免設(shè)置主鍵的時(shí)候使用無(wú)序ID進(jìn)行插入操作钙勃,因?yàn)檫@樣會(huì)導(dǎo)致一直在進(jìn)行頁(yè)分裂和頁(yè)合并的操作(后面會(huì)寫(xiě)一篇文章細(xì)說(shuō)頁(yè)分裂和頁(yè)合并)蛛碌。
- 不要設(shè)置過(guò)長(zhǎng)的值作為聚簇索引的值,因?yàn)檩o助索引的葉子節(jié)點(diǎn)上存放了聚簇索引的值辖源,會(huì)使得每一份輔助索引都特別的大蔚携,占用更多的物理空間。