
概述
前言
數(shù)據(jù)庫(kù)索引是數(shù)據(jù)庫(kù)的重要組成部分,無(wú)論在日常開(kāi)發(fā)還是在數(shù)據(jù)庫(kù)面試中都占有很重要,是后端開(kāi)發(fā)人員在行業(yè)內(nèi)生存的必備技能。下文我們就以下面這幾個(gè)問(wèn)題對(duì)數(shù)據(jù)庫(kù)索引進(jìn)行展開(kāi)分析
- 為什么要使用索引
- 索引的數(shù)據(jù)結(jié)構(gòu)
- 索引的類(lèi)型
- 密集索引和稀疏索引
- 索引的優(yōu)缺點(diǎn)
- 怎樣創(chuàng)建合理的索引
問(wèn)題分析
1.為什么要使用索引
這個(gè)就要討論一下索引的作用了,索引的作用很容易理解。索引就是數(shù)據(jù)庫(kù)數(shù)據(jù)的目錄,在數(shù)據(jù)量很大情況下可以避免進(jìn)行全表掃描查找數(shù)據(jù),其實(shí)就是幫助我們更快速的定位到數(shù)據(jù),說(shuō)白了就是加快查找速度
2.索引的數(shù)據(jù)結(jié)構(gòu)
這里就不長(zhǎng)篇大論各種數(shù)據(jù)結(jié)構(gòu)了,就列出幾種常見(jiàn)的索引數(shù)據(jù)結(jié)構(gòu)
- B-tree(B樹(shù))
- B+-tree(B+樹(shù))
- B*tree(B*樹(shù))
- Hash
MySQL數(shù)據(jù)庫(kù)索引的數(shù)據(jù)結(jié)構(gòu)就是B+樹(shù),對(duì)這些數(shù)據(jù)結(jié)構(gòu)有興趣的同學(xué)戳這里:https://zhuanlan.zhihu.com/p/27700617
3.索引的類(lèi)型(MySQL)
- 主鍵索引:字段不能重復(fù),不能有null,一張表只有一個(gè)主鍵索引
- 唯一鍵索引:字段不能重復(fù),可以有null,一張表可以有多個(gè)唯一索引
- 普通索引:對(duì)字段沒(méi)有特定要求,幫助提高查詢(xún)速度
- 組合索引:多個(gè)字段組成索引,用于組合搜索
- 全文索引:對(duì)文本的內(nèi)容進(jìn)行分詞,進(jìn)行搜索(MyISAM才有)
4.密集索引和稀疏索引
先說(shuō)密集索引和稀疏索引的區(qū)別吧
- 數(shù)據(jù)庫(kù)表中數(shù)據(jù)的物理存儲(chǔ)順序和索引的順序一樣,因?yàn)槲锢泶鎯?chǔ)順序只有一種,所以一張表也只能有一個(gè)密集索引。索引樹(shù)的葉子節(jié)點(diǎn)存儲(chǔ)的就是行數(shù)據(jù)(索引樹(shù)和數(shù)據(jù)是存儲(chǔ)在一起的)
- 數(shù)據(jù)庫(kù)表中數(shù)據(jù)的物理存儲(chǔ)順序和索引的順序不一樣,索引樹(shù)的葉子節(jié)點(diǎn)存儲(chǔ)的是指向數(shù)據(jù)的指針(數(shù)據(jù)和索引樹(shù)分開(kāi)存儲(chǔ))
InnoDB和MyISAM的索引
- MyISAM
-
MyISAM中不論是主鍵索引、還是任何其他鍵值索引都是稀疏索引,并且每個(gè)索引樹(shù)之間沒(méi)有聯(lián)系。索引樹(shù)葉子節(jié)點(diǎn)中存儲(chǔ)的是指向數(shù)據(jù)的指針,對(duì)任何一個(gè)索引進(jìn)行一次索引查找(不依賴(lài)于其他索引樹(shù))就能找到數(shù)據(jù)
MyISAM
如上圖,不管是通過(guò)主鍵索引查找還是其他鍵索引查找,查找一顆索引樹(shù)找到指向數(shù)據(jù)的指針后就能找到數(shù)據(jù)
- InnoDB
- InnoDB必須有且只有一個(gè)密集索引;數(shù)據(jù)表如果中定義了主鍵,則主鍵作為密集索引;數(shù)據(jù)表入如果沒(méi)有定義主鍵則第一個(gè)唯一非空索引作為密集索引;如果兩個(gè)條件都不滿(mǎn)足,InnoDB內(nèi)部會(huì)生成一個(gè)隱藏主鍵作為密集索引。當(dāng)通過(guò)密集索引進(jìn)行查找時(shí),只需要一次索引查找就能就到數(shù)據(jù)
-
除了密集索引(一般情況是主鍵索引,上面說(shuō)了)外的其他鍵索引都可以說(shuō)是稀疏索引,但是這里的稀疏索引和MyISAM中的稀疏索引有些不同,不同在于哪里?
上文指出了MyISAM的稀疏索引“對(duì)任何一個(gè)索引樹(shù)進(jìn)行一次索引查找(不依賴(lài)于其他索引樹(shù))就能找到數(shù)據(jù)”,但是在InnoDB中根據(jù)稀疏索引查找數(shù)據(jù)時(shí)需要查找兩顆索引樹(shù)(二次查找),因?yàn)镮nnoDB中稀疏索引樹(shù)中葉子節(jié)點(diǎn)存儲(chǔ)的是密集索引的鍵值而不是指向數(shù)據(jù)的指針,下面圖解
InnoDB
如上圖,如果以主鍵作為密集索引。看綠色線(xiàn)條,當(dāng)使用主鍵索引(密集索引)進(jìn)行查找時(shí),只需要對(duì)主鍵索引進(jìn)行查找就能找到數(shù)據(jù);看紅色線(xiàn)條,當(dāng)使用其他鍵創(chuàng)建的稀疏索引進(jìn)行搜索時(shí),第一步先從稀疏索引中查找到id值(主鍵值),第二步在密集索引中根據(jù)第一步找到的id值(主鍵值)找到數(shù)據(jù),這就是常說(shuō)的“二次查找”問(wèn)題。也就是在InnoDB中不論通過(guò)哪個(gè)索引查找數(shù)據(jù),一定會(huì)經(jīng)過(guò)密集索引
- 總結(jié)InnoDB和MyISAM的索引區(qū)別
- InnoDB主鍵索引是密集索引,MyISAM主鍵索引是稀疏索引
- InnoDB其他鍵索引葉子節(jié)點(diǎn)存儲(chǔ)密集索引的鍵值(一般是主鍵值),MyISAM其他鍵索引葉子節(jié)點(diǎn)存儲(chǔ)指向數(shù)據(jù)存儲(chǔ)位置的指針
- InnoDB數(shù)據(jù)和索引存儲(chǔ)在一個(gè)文件,MyISAM數(shù)據(jù)和索引分開(kāi)存儲(chǔ)
5.索引的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 提高查找數(shù)據(jù)的效率,這也是創(chuàng)建索引的主要目的
- 通過(guò)創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性
- 可以加速表和表之間的連接,特別是在實(shí)現(xiàn)數(shù)據(jù)的參考完整性方面特別有意義
- 在使用分組和排序 子句進(jìn)行數(shù)據(jù)檢索時(shí),同樣可以顯著減少查詢(xún)中分組和排序的時(shí)間
- 通過(guò)使用索引,可以在查詢(xún)的過(guò)程中,使用優(yōu)化隱藏器,提高系統(tǒng)的性能
雖然索引的好處有這么多,但也不是創(chuàng)建越多越好,下面說(shuō)一下索引的缺點(diǎn)
缺點(diǎn)
- 索引占用磁盤(pán)空間,索引越多占用磁盤(pán)空間越大
- 維護(hù)索引需要大量時(shí)間,并且隨著數(shù)據(jù)量的增長(zhǎng)而增長(zhǎng)
- 對(duì)數(shù)據(jù)進(jìn)行增刪改時(shí),由于索引也需要?jiǎng)討B(tài)維護(hù),增刪改的效率會(huì)變低,索引越多,增刪改的效率越低
6.怎樣創(chuàng)建合理的索引
索引的優(yōu)缺點(diǎn)我們都知道了,那要怎樣創(chuàng)建索引才合理呢?
- 主鍵默認(rèn)就是主鍵索引
- 數(shù)據(jù)量較大的表才考慮創(chuàng)建索引
- 有頻繁的數(shù)據(jù)寫(xiě)入操作的表不要過(guò)多的索引
- 經(jīng)常出現(xiàn)在where子句或者經(jīng)常用于連接的字段最好創(chuàng)建索引
- 太長(zhǎng)的文本字段不要?jiǎng)?chuàng)建索引

