對于學(xué)習(xí)計算機(jī)理論知識而言庶弃,最好的方式就是問自己幾個問題衫贬,然后去思考,搜索從而找出問題的答案歇攻。
1.索引是什么呢固惯?
數(shù)據(jù)庫索引是一種數(shù)據(jù)結(jié)構(gòu),它以維護(hù)索引數(shù)據(jù)結(jié)構(gòu)的額外寫操作和存儲空間為代價缴守,提高了對數(shù)據(jù)庫表進(jìn)行數(shù)據(jù)檢索操作的速度葬毫。索引用于快速定位數(shù)據(jù),而不必每次訪問數(shù)據(jù)庫表時都在數(shù)據(jù)庫表中搜索每一行屡穗√瘢可以使用數(shù)據(jù)庫表的一列或多列來創(chuàng)建索引,這為快速隨機(jī)查找和有效訪問有序記錄提供了基礎(chǔ)村砂。
? --Wiki翻譯版
對于相關(guān)專業(yè)的人來說烂斋,這個問題很好回答。我們在理解上可以認(rèn)為索引就是類似于字典目錄一樣的東西,通過它可以快速定位到數(shù)據(jù)汛骂。
2.索引的數(shù)據(jù)結(jié)構(gòu)是什么呢罕模?
在MySQL中使用的數(shù)據(jù)結(jié)構(gòu)為B+樹作為索引,我們可以簡單來分析下為什么要使用B+樹作為索引呢帘瞭?
前提假設(shè)你知道二叉樹的基本知識:左小右大手销,無節(jié)點(diǎn)相等
-
假如使用二叉樹作為索引,這樣做的不好處是图张,會形成一個極端的查詢樹
極端二叉樹
使用AVL樹的作為索引锋拖,這樣做的不好處是,它是一個平衡二叉樹祸轮,當(dāng)對數(shù)據(jù)進(jìn)行一些刪除增加操作的時候兽埃,AVL樹會使用旋轉(zhuǎn)的方式來調(diào)整樹結(jié)構(gòu)。這樣來看适袜,維護(hù)這顆樹的代價過于高昂柄错。
-
使用紅黑樹最為索引,這樣做的不好處
- 從存儲的基本單位來說苦酱,計算機(jī)存儲分配都是按頁對齊的售貌,數(shù)據(jù)庫系統(tǒng)巧妙的設(shè)計了磁盤的預(yù)讀原理,一次IO最好能讀一頁的內(nèi)容疫萤。但是對于紅黑樹而言颂跨,它的一個父節(jié)點(diǎn)最多只有兩個子節(jié)點(diǎn),包含的數(shù)據(jù)不夠一頁的內(nèi)容扯饶,而且深度過高恒削,會到這IO次數(shù)頻繁。所以紅黑樹這種數(shù)據(jù)結(jié)構(gòu)應(yīng)用場景適合在內(nèi)存中尾序,比如HashMap的查詢結(jié)構(gòu)中使用钓丰。
-
使用B樹作為索引,和B+樹相比這樣的不好處是
B樹和B+樹最重要的一個區(qū)別就是B+樹只有葉節(jié)點(diǎn)存放數(shù)據(jù)每币,其余節(jié)點(diǎn)用來索引携丁,而B樹是每個索引節(jié)點(diǎn)都會有Data域。
一次讀寫IO的數(shù)據(jù)量是一定的兰怠,就是說梦鉴,當(dāng)B樹中攜帶數(shù)據(jù)的時候,一次讀寫的索引數(shù)遠(yuǎn)小于不B+樹痕慢。
另一個優(yōu)點(diǎn)是尚揣,B+樹有個優(yōu)化躏吊,將所有的葉子節(jié)點(diǎn)用指針串起來谆沃。這樣遍歷葉子節(jié)點(diǎn)就能獲得全部數(shù)據(jù),這樣就能進(jìn)行區(qū)間訪問偎漫。
這就是為什么使用B+樹作為索引的原因。
3.既然Hash所以查詢速率只有O(1)方篮,為什么不使用名秀?
1.Hash索引在最好的情況下會是O(1)的查詢效率,但是當(dāng)一些極端情況下藕溅,也會導(dǎo)致大量數(shù)據(jù)存在一個Bucket中匕得,所以查詢速率不一定比B+樹快。
2.Hash索引不能進(jìn)行范圍查詢巾表,不能進(jìn)行排序汁掠。
3.Hash索引不能進(jìn)行組合索引中的部分索引查詢。
4.不能避免表掃描集币,因?yàn)橥ㄟ^Hash值查找到鏈表之后考阱,還是得通過實(shí)際值對比才能確認(rèn)。
4.位圖索引是什么鞠苟?
位圖索引和布隆過濾器的設(shè)計結(jié)構(gòu)有點(diǎn)相似乞榨,簡單來說就是使用0 1的方式來進(jìn)行數(shù)據(jù)類型或者值的判定。由于這種特性当娱,位圖索引在進(jìn)行讀寫操作的時候吃既,必須嚴(yán)格使用強(qiáng)鎖進(jìn)行操作。所以它的一個缺點(diǎn)就是不適合高并發(fā)的操作下的數(shù)據(jù)庫讀寫操作跨细。適合統(tǒng)計運(yùn)算較多鹦倚。
5.密集索引和稀疏索引的區(qū)別是什么?
1.密集索引文件中的每個搜索碼值都對應(yīng)一個索引值扼鞋。
密集索引決定了表中的物理排列順序申鱼。在InnoDB中有且只有一個密集索引愤诱,主鍵被定義了云头,主鍵就是唯一索引。若沒有唯一非空索引淫半,InnoDB內(nèi)部就會生成一個隱藏主鍵溃槐。
select * from person where id = 7;
例如之上的sql語句就會直接走密集索引查詢到相關(guān)的行。
稀疏索引查詢的流程是先查找到它的id科吭,然后再去密集索引查找到具體的行昏滴。例如:
select * from person where age=18;
在查詢的內(nèi)部操作中,是先查找到age=18
對應(yīng)的所有數(shù)據(jù)的id对人,然后再走密集索引的方式查找的所屬的行谣殊。
6.聯(lián)合索引最左匹配原則的成因?
最左前綴匹配原則牺弄,非常重要的原則姻几,MySQL會一直向右匹配直到遇到范圍查詢(>、<、between蛇捌、like)
就停止匹配抚恒,比如a = 1 and b = 2 and c > 3 and d = 4
如果建立(a,b,c,d)
順序的索引,d是用不到索引的络拌,如果建立(a,b,d,c)
的索引則都可以用到俭驮,a,b,d的順序可以任意調(diào)整。=
和in
可以亂序春贸,比如a = 1 and b = 2 and c = 3
建立(a,b,c)
索引可以任意順序混萝,MySQL的查詢優(yōu)化器會幫你優(yōu)化成索引可以識別的形式。
聯(lián)合索引最左匹配原則的成因是因?yàn)槠妓。?lián)合所以需要在第一個索引字段上進(jìn)行排序譬圣,在第一個字段的基礎(chǔ)上對第二個字段進(jìn)行查找。所以第二個字段是用不到索引的雄坪。
7.索引是建立的越多越好么厘熟?
數(shù)據(jù)量小的表不需要建立索引,建立所以會增加開銷维哈。