淺談MySQL的索引(1)

??????索引齿拂,不光是我們再工作中時常用到的一個名詞凿可,在面試的時候也是逢考必面的知識點状囱,索引可以讓我們的速度提升千百倍效率掰曾,也可以讓我們本來運行很ok的sql變的不那么“和諧”旭蠕,接下來我們就聊聊索引。


一旷坦、什么是索引


??? MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)掏熬。

我們可以簡單理解為:快速查找排好序的一種數(shù)據(jù)結(jié)構(gòu)。

或者理解為一本書的目錄秒梅,個人認為重點是“有序”旗芬。


  • 索引的本質(zhì)就是數(shù)據(jù)庫中字段值的復制,該字段稱為索引的關(guān)鍵字捆蜀;

  • 索引也是一張表疮丛,記錄保存了主鍵與索引字段,并指向了實際表數(shù)據(jù)辆它;

  • 索引往往通過復雜的數(shù)據(jù)結(jié)構(gòu)(雙向鏈表誊薄、hash、BTree/B+Tree锰茉、)實現(xiàn)呢蔫;


  • MyISAM存儲引擎的表支持主索引,InnoDB存儲引擎的表支持聚簇索引(主索引)與非聚簇索引(輔助索引)索引優(yōu)化使用飒筑。


    二片吊、主流索引查找算法


  • 線性查找绽昏,是一個鏈表,要搜索的話俏脊,需要從第一個往后一個個找

  • 二分查找全谤,是線性查找的升級,也就是說二分查找是可以用線性查找的數(shù)據(jù)接口联予,但是算法不一樣

  • 二叉樹查找啼县,進一步提高性能材原,引入了二叉樹

  • 平衡二叉樹沸久,二叉樹因為有平衡的問題,又進一步出現(xiàn)了平衡二叉樹

  • B樹余蟹,在平衡二叉樹之后又發(fā)現(xiàn)了一個問題卷胯,之前的數(shù)據(jù)結(jié)構(gòu)每一個節(jié)點都是一個行數(shù)據(jù),這樣的話對于磁盤的利用率是有問題的威酒,因為我的數(shù)據(jù)要最終落到磁盤上窑睁,以一個節(jié)點為單位去讀取磁盤效率是很低的

  • B+樹,B樹效率也有問題葵孤,出現(xiàn)了B+樹担钮,可以理解B+樹是B樹和線性的結(jié)合


  • 二、索引 的分類

  • 從索引存儲結(jié)構(gòu)劃分:B Tree索引尤仍、Hash索引箫津、FULLTEXT全文索引以及R Tree索引

  • 從應用層次劃分:普通索引、唯一索引宰啦、主鍵索引苏遥、復合索引

  • 從鍵值劃分:主鍵、輔助

  • 從數(shù)據(jù)存儲以及索引邏輯關(guān)系劃分:聚集索引赡模、非聚集索引

  • 而Mysql索引主要有兩種結(jié)構(gòu):B+Tree索引和Hash索引田炭。我們平常所說的索引,如果沒有特別指明漓柑,一般都是指B樹結(jié)構(gòu)組織的索引(B+Tree索引)教硫。


    接下來我們就一一介紹一下各個索引名詞:


    2.1、BTree 索引

    ????????BTree? 全稱?Balanced Tree辆布,是一種很普遍的數(shù)據(jù)庫索引結(jié)構(gòu)栋豫,oracle默認的索引類型。

    ????????其特點是定位高效谚殊、利用率高丧鸯、自我平衡,特別適用于高基數(shù)字段嫩絮,定位單條或小范圍數(shù)據(jù)非常高效丛肢。理論上围肥,使用Btree在億條數(shù)據(jù)與100條數(shù)據(jù)中定位記錄的花銷相同。


    演算如下:
    讀取root節(jié)點蜂怎,判斷82大于在0-120之間穆刻,走左邊分支。
    讀取左邊branch節(jié)點杠步,判斷82大于80且小于等于120氢伟,走右邊分支。
    讀取右邊leaf節(jié)點幽歼,在該節(jié)點中找到數(shù)據(jù)82及對應的rowid
    使用rowid去物理表中讀取記錄數(shù)據(jù)塊(如果是count或者只select rowid朵锣,則最后一次讀取不需要)


    ????而由于Btree索引對結(jié)構(gòu)的利用率很高,定位高效甸私。當1千萬條數(shù)據(jù)時诚些,Btree索引也是三層結(jié)構(gòu)(依稀記得億級數(shù)據(jù)才是3層與4層的分水嶺)。定位記錄仍只需要三次I/O皇型,這便是開頭所說的诬烹,100條數(shù)據(jù)和1千萬條數(shù)據(jù)的定位,在btree索引中的花銷是一樣的弃鸦。


    Btree索引的自我平衡(平衡擴張)借用下面幾張圖進行說明:


    ?????新建一個索引绞吁,索引上只會有一個leaf節(jié)點,取名為Node A唬格,不斷的向這個leaf節(jié)點中插入數(shù)據(jù)后家破,直到這個節(jié)點滿;


    ??????當Node A滿之后西轩,我們再向表中插入一條記錄员舵,此時索引就需要做拆分處理:會新分配兩個數(shù)據(jù)塊NodeB & C,如果新插入的值藕畔,大于當前最大值马僻,則將Node A中的值全部插入Node B中,將新插入的值放到Node C中注服;否則按照5-5比例韭邓,將已有數(shù)據(jù)分別插入到NodeB與C中;


    無論采用哪種分割方式溶弟,之前的leaf節(jié)點A女淑,將變成一個root節(jié)點,保存兩個范圍條目辜御,指向B與C鸭你,結(jié)構(gòu)如下圖:


    當Node C滿之后,此時 Node A仍有空余空間存放條目,所以不需要再拆分袱巨,而只是新分配一個數(shù)據(jù)塊Node D阁谆,將在Node A中創(chuàng)建指定到Node D的條目:


    如果當根節(jié)點Node A也滿了,則需要進一步拆分:新建Node E&F&G愉老,將Node A中范圍條目拆分到E&F兩個節(jié)點中场绿,并建立E&F到BCD節(jié)點的關(guān)聯(lián),向Node G插入索引值嫉入。此時E&F為branch節(jié)點焰盗,G為leaf節(jié)點,A為Root節(jié)點:


    在整個擴張過程中咒林,Btree自身總能保持平衡熬拒,Leaf節(jié)點的深度能一直保持一致。

    參考文章:http://zsuil.com/?p=1184


    2.2映九、B+Tree索引

    MySQL數(shù)據(jù)庫索引采用的是B+Tree結(jié)構(gòu)梦湘,在B-Tree結(jié)構(gòu)上做了優(yōu)化改造瞎颗,其特點:

  • 只有葉子節(jié)點包含索引和數(shù)據(jù)

  • 非葉子節(jié)點只存儲索引值

  • 葉子節(jié)點用指針連接件甥,提高區(qū)間訪問性能

  • 對比B樹來說,B+樹范圍查找時哼拔,只需要定位倆個節(jié)點的索引值引有,然后利用葉子節(jié)點指針進行遍歷即可,而B樹需要遍歷范圍內(nèi)所有的節(jié)點數(shù)據(jù)倦逐,倆相對比譬正,B+樹效率更高




  • 2.3、Hash 索引

    ????Hash索引是基于Hash表實現(xiàn)檬姥,只有查詢條件精確匹配Hash索引中的所有列時曾我,才能夠使用到Hash索引。也就是說健民,Hash索引只能用在等值查詢抒巢,那么范圍和模糊查詢就不可以了;存儲結(jié)構(gòu)如下圖:


    ????對于Hash索引中的所有列秉犹,存儲引擎都會為每一行計算一個Hash碼蛉谜,Hash索引中儲存的就是Hash碼。

    ????Hash索引表中保存每一個Hash索引所代表的數(shù)據(jù)行的指針崇堵,由于Hash索引本身只存儲Hash碼型诚,所以Hash索引結(jié)構(gòu)比較緊湊,那么查詢速度比較快鸳劳。


    2.2狰贯、FULLTEXT全文索引

    全文索引,通過建立倒排索引,可以極大的提升檢索效率,解決判斷字段是否包含的問題.?


    例如: 有title字段,需要查詢所有包含 "政府"的記錄. 需要 like "%政府%"方式查詢,查詢速度慢,當查詢包含"政府" OR "中國"的需要是,sql難以簡單滿足.全文索引就可以實現(xiàn)這個功能.


    舊版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。?

    不過新版的MySQL5.6.24上InnoDB引擎也加入了全文索引涵紊,所以具體信息要隨時關(guān)注官網(wǎng)还绘,

    --?方式1、創(chuàng)建表的同時創(chuàng)建全文索引CREATE?TABLE?article?(????id?INT?AUTO_INCREMENT?NOT?NULL?PRIMARY?KEY,????title?VARCHAR(200),?????????body?TEXT,?????????FULLTEXT(title,?body)?)?TYPE=MYISAM;?--?方式2.通過?alter?table?的方式來添加ALTER?TABLE?`student`?ADD?FULLTEXT?INDEX?ft_stu_name??(`name`)?;??--?ft_stu_name是索引名栖袋,可以隨便起??--?或者:ALTER?TABLE?`student`?ADD?FULLTEXT?ft_stu_name??(`name`);--?方式3.?直接通過create?index的方式CREATE?FULLTEXT?INDEX?ft_email_name?ON?`student`?(`name`);??--?也可以在創(chuàng)建索引的時候指定索引的長度:CREATE?FULLTEXT?INDEX?ft_email_name?ON?`student`?(`name`(20));

    使用全文索引

    ?使用全文索引的格式:??MATCH?(columnName)?AGAINST?('string');?eg:?????????SELECT?*?FROM?`student`?WHERE?MATCH(`name`)?AGAINST('聰');????????當查詢多列數(shù)據(jù)時:?????????建議在此多列數(shù)據(jù)上創(chuàng)建一個聯(lián)合的全文索引拍顷,否則使用不了索引的。???????SELECT?*?FROM?`student`?WHERE?MATCH(`name`,`address`)?AGAINST('聰?廣東');


    不知不覺寫到這已經(jīng)2k多字了塘幅,本期我們就寫到這里昔案,下期我們繼續(xù)

    探討索引。
    …………………………………分割線……………………………

    不積跬步电媳,無以至千里踏揣;不積小流,無以成江海匾乓。

    我都墨跡這么半天了 捞稿,你不點關(guān)注,不點贊拼缝,不收藏娱局,還不轉(zhuǎn)發(fā),你想干啥_制摺Kテ搿!继阻!

    關(guān)注我耻涛,每天分享一些小知識點。分享自己的小心得瘟檩,包含但不限于初抹缕、中、高級面試題呦D痢W垦小!

    最后編輯于
    ?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
    • 序言:七十年代末背蟆,一起剝皮案震驚了整個濱河市鉴分,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌带膀,老刑警劉巖志珍,帶你破解...
      沈念sama閱讀 211,123評論 6 490
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垛叨,居然都是意外死亡伦糯,警方通過查閱死者的電腦和手機柜某,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 90,031評論 2 384
    • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敛纲,“玉大人喂击,你說我怎么就攤上這事∮傧瑁” “怎么了翰绊?”我有些...
      開封第一講書人閱讀 156,723評論 0 345
    • 文/不壞的土叔 我叫張陵,是天一觀的道長旁壮。 經(jīng)常有香客問我监嗜,道長,這世上最難降的妖魔是什么抡谐? 我笑而不...
      開封第一講書人閱讀 56,357評論 1 283
    • 正文 為了忘掉前任裁奇,我火速辦了婚禮,結(jié)果婚禮上麦撵,老公的妹妹穿的比我還像新娘刽肠。我一直安慰自己,他們只是感情好免胃,可當我...
      茶點故事閱讀 65,412評論 5 384
    • 文/花漫 我一把揭開白布音五。 她就那樣靜靜地躺著,像睡著了一般杜秸。 火紅的嫁衣襯著肌膚如雪放仗。 梳的紋絲不亂的頭發(fā)上润绎,一...
      開封第一講書人閱讀 49,760評論 1 289
    • 那天撬碟,我揣著相機與錄音,去河邊找鬼莉撇。 笑死呢蛤,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的棍郎。 我是一名探鬼主播其障,決...
      沈念sama閱讀 38,904評論 3 405
    • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼涂佃!你這毒婦竟也來了励翼?” 一聲冷哼從身側(cè)響起,我...
      開封第一講書人閱讀 37,672評論 0 266
    • 序言:老撾萬榮一對情侶失蹤辜荠,失蹤者是張志新(化名)和其女友劉穎汽抚,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體伯病,經(jīng)...
      沈念sama閱讀 44,118評論 1 303
    • 正文 獨居荒郊野嶺守林人離奇死亡造烁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
      茶點故事閱讀 36,456評論 2 325
    • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惭蟋。...
      茶點故事閱讀 38,599評論 1 340
    • 序言:一個原本活蹦亂跳的男人離奇死亡苗桂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出告组,到底是詐尸還是另有隱情煤伟,我是刑警寧澤,帶...
      沈念sama閱讀 34,264評論 4 328
    • 正文 年R本政府宣布木缝,位于F島的核電站持偏,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏氨肌。R本人自食惡果不足惜鸿秆,卻給世界環(huán)境...
      茶點故事閱讀 39,857評論 3 312
    • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望怎囚。 院中可真熱鬧卿叽,春花似錦、人聲如沸恳守。這莊子的主人今日做“春日...
      開封第一講書人閱讀 30,731評論 0 21
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽催烘。三九已至沥阱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伊群,已是汗流浹背考杉。 一陣腳步聲響...
      開封第一講書人閱讀 31,956評論 1 264
    • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留舰始,地道東北人崇棠。 一個月前我還...
      沈念sama閱讀 46,286評論 2 360
    • 正文 我出身青樓,卻偏偏與公主長得像丸卷,于是被迫代替她去往敵國和親枕稀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
      茶點故事閱讀 43,465評論 2 348

    推薦閱讀更多精彩內(nèi)容

    • 個人專題目錄[http://www.reibang.com/p/140e2a59db2c] 1. 性能下降SQL...
      Java及SpringBoot閱讀 1,281評論 0 4
    • 索引的分類 從存儲結(jié)構(gòu)上來劃分: BTree索引(B-Tree或B+Tree索引)谜嫉,Hash索引萎坷,full-ind...
      double_hi閱讀 305評論 0 0
    • 先來看個問題 假設現(xiàn)在有100000條從0到10000且從大到小排列的整型數(shù)據(jù),1條數(shù)據(jù)的大小假設(真的只是假設)...
      kindol閱讀 526評論 0 2
    • 說到索引沐兰,很多人都知道“索引是一個排序的列表哆档,在這個列表中存儲著索引的值和包含這個值的數(shù)據(jù)所在行的物理地址,在數(shù)據(jù)...
      愛情小傻蛋閱讀 678評論 2 2
    • 一僧鲁、MySQL中索引的語法 創(chuàng)建索引 在創(chuàng)建表的時候添加索引 在創(chuàng)建表以后添加索引 注意: 索引需要占用磁盤空間虐呻,...
      _大叔_閱讀 202評論 0 1