技術(shù)文章第一時(shí)間送達(dá)!
看了很多關(guān)于索引的博客,講的大同小異。但是始終沒有讓我明白關(guān)于索引的一些概念,如B-Tree索引,Hash索引,唯一索引….或許有很多人和我一樣,沒搞清楚概念就開始研究B-Tree,B+Tree等結(jié)構(gòu),導(dǎo)致在面試的時(shí)候答非所問! 索引是什么?索引是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)。 索引能干什么?提高數(shù)據(jù)查詢的效率。 索引:排好序的快速查找數(shù)據(jù)結(jié)構(gòu)!索引會(huì)影響where后面的查找,和order by 后面的排序。 一、索引的分類1??從存儲(chǔ)結(jié)構(gòu)上來劃分:BTree索引(B-Tree或B+Tree索引),Hash索引,full-index全文索引,R-Tree索引。 2??從應(yīng)用層次來分:普通索引,唯一索引,復(fù)合索引。 3??根據(jù)中數(shù)據(jù)的物理順序與鍵值的邏輯(索引)順序關(guān)系:聚集索引,非聚集索引。 1??中所描述的是索引存儲(chǔ)時(shí)保存的形式,2??是索引使用過程中進(jìn)行的分類,兩者是不同層次上的劃分。不過平時(shí)講的索引類型一般是指在應(yīng)用層次的劃分。 就像手機(jī)分類,安卓手機(jī),IOS手機(jī) 與 華為手機(jī),蘋果手機(jī),OPPO手機(jī)一樣。
二、索引的底層實(shí)現(xiàn)
不談存儲(chǔ)引擎,只討論實(shí)現(xiàn)(抽象) Hash索引基于哈希表實(shí)現(xiàn),只有精確匹配索引所有列的查詢才有效,對(duì)于每一行數(shù)據(jù),存儲(chǔ)引擎都會(huì)對(duì)所有的索引列計(jì)算一個(gè)哈希碼(hash code),并且Hash索引將所有的哈希碼存儲(chǔ)在索引中,同時(shí)在索引表中保存指向每個(gè)數(shù)據(jù)行的指針。 B-Tree能加快數(shù)據(jù)的訪問速度,因?yàn)榇鎯?chǔ)引擎不再需要進(jìn)行全表掃描來獲取數(shù)據(jù),數(shù)據(jù)分布在各個(gè)節(jié)點(diǎn)之中。 是B-Tree的改進(jìn)版本,同時(shí)也是數(shù)據(jù)庫索引索引所采用的存儲(chǔ)結(jié)構(gòu)。數(shù)據(jù)都在葉子節(jié)點(diǎn)上,并且增加了順序訪問指針,每個(gè)葉子節(jié)點(diǎn)都指向相鄰的葉子節(jié)點(diǎn)的地址。相比B-Tree來說,進(jìn)行范圍查找時(shí)只需要查找兩個(gè)節(jié)點(diǎn),進(jìn)行遍歷即可。而B-Tree需要獲取所有節(jié)點(diǎn),相比之下B+Tree效率更高。 案例:假設(shè)有一張學(xué)生表,id為主鍵 在MyISAM引擎中的實(shí)現(xiàn)(二級(jí)索引也是這樣實(shí)現(xiàn)的) 在InnoDB中的實(shí)現(xiàn) 三、問題問:為什么索引結(jié)構(gòu)默認(rèn)使用B-Tree,而不是hash,二叉樹,紅黑樹? hash:雖然可以快速定位,但是沒有順序,IO復(fù)雜度高。 二叉樹:樹的高度不均勻,不能自平衡,查找效率跟數(shù)據(jù)有關(guān)(樹的高度),并且IO代價(jià)高。 紅黑樹:樹的高度隨著數(shù)據(jù)量增加而增加,IO代價(jià)高。 問:為什么官方建議使用自增長主鍵作為索引。 結(jié)合B+Tree的特點(diǎn),自增主鍵是連續(xù)的,在插入過程中盡量減少頁分裂,即使要進(jìn)行頁分裂,也只會(huì)分裂很少一部分。并且能減少數(shù)據(jù)的移動(dòng),每次插入都是插入到最后。總之就是減少分裂和移動(dòng)的頻率。 插入連續(xù)的數(shù)據(jù): 插入非連續(xù)的數(shù)據(jù) |
|