JAVA面試被問(wèn)mysql聚集索引和非聚集索引的區(qū)別?
索引這個(gè)詞在數(shù)據(jù)庫(kù)知識(shí)中耳熟能詳,是一種以空間換取時(shí)間的典型,索引結(jié)構(gòu)往往能給數(shù)據(jù)操作帶來(lái)十分顯著的性能提升,我們都知道大多數(shù)的數(shù)據(jù)庫(kù)默認(rèn)的索引結(jié)構(gòu)都是B+樹(shù),而聚集索引和非聚集索引(也叫輔助索引)都屬于B+樹(shù)結(jié)構(gòu);
所以首先我們簡(jiǎn)單了解下B+樹(shù):
B+樹(shù):是一種高度平衡的為磁盤(pán)數(shù)據(jù)存取而設(shè)計(jì)的查找樹(shù)結(jié)構(gòu),所有的數(shù)據(jù)節(jié)點(diǎn)從左到右都是按順序存放在同一層的葉子節(jié)點(diǎn)上,這就為數(shù)據(jù)的順序查找或者范圍查找提供了極大的便利,查詢效率使用大O表示法為O(logN);
mysql使用B+樹(shù)存取數(shù)據(jù),相對(duì)于所有數(shù)據(jù)的順序查找來(lái)說(shuō),磁盤(pán)IO的速度相當(dāng)?shù)拖拢鳥(niǎo)+樹(shù)的查找往往只需要幾次的磁盤(pán)IO,效率是十分驚人的;
回到問(wèn)題本身,聚集索引和非聚集索引的區(qū)別是什么?最根本的區(qū)別在于索引的順序和表數(shù)據(jù)的順序是否一致。。
①聚集索引:使用聚集索引的表,記錄和索引保持著一致的順序,這樣只要找到索引的值就能直接從葉子節(jié)點(diǎn)里面獲取到全部列數(shù)據(jù);

②非聚集索引:記錄和索引的順序往往不同,可理解為索引下面的葉子節(jié)點(diǎn)存儲(chǔ)的還是索引,想要獲得真正的列數(shù)據(jù),還需要再一次查詢;

根據(jù)上面的描述,聚集索引常常用在重復(fù)值不多(數(shù)據(jù)庫(kù)通常會(huì)自動(dòng)加內(nèi)置的rowID保證列成為唯一索引),長(zhǎng)度不大的列(比如主鍵等),而且聚集索引十分適合于順序查詢(order by)和范圍查詢(between,>,<),但是不適合于頻繁修改的列,和大字段的列,因?yàn)檫@會(huì)導(dǎo)致數(shù)據(jù)在磁盤(pán)上大量移動(dòng)的性能消耗;
而非聚集索引更常被用于頻繁更新的列,列長(zhǎng)度比較大的場(chǎng)景;
有人做過(guò)形象的比喻,聚集索引就像是使用拼音查字典(比如b就是100-150頁(yè)),而非聚集索引是使用部首查字典(比如弓在100頁(yè),張?jiān)?00頁(yè))!
場(chǎng)景適用性截圖如下:

在下列場(chǎng)景中,不應(yīng)該使用索引:
1,表數(shù)據(jù)不多:表數(shù)據(jù)不多的時(shí)候,磁盤(pán)IO本來(lái)就少,加索引只會(huì)增加IO開(kāi)銷;
2,不常使用的列:沒(méi)必要;
3,頻繁更新的列:插入和刪除時(shí)需要額外維護(hù)一份索引數(shù)據(jù),會(huì)影響總的效率;

