0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

對 B+ 樹與索引在 MySQL 中的認識

數(shù)據(jù)分析與開發(fā) ? 來源:博客園 ? 作者:AnnsShadoW ? 2021-11-08 11:11 ? 次閱讀

概述

本質(zhì):數(shù)據(jù)庫維護某種數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù)

索引取舍原則:索引的結(jié)構(gòu)組織要盡量減少查找過程中磁盤I/O的存取次數(shù)

B樹

滿足的條件

d為大于1的一個正整數(shù),稱為B-Tree的度

h為一個正整數(shù),稱為B-Tree的高度

每個非葉子節(jié)點由n-1個key和n個指針組成,其中d《=n《=2d

每個葉子節(jié)點最少包含一個key和兩個指針,最多包含2d-1個key和2d個指針,葉節(jié)點的指針均為null

所有葉節(jié)點具有相同的深度,等于樹高h

key和指針互相間隔,節(jié)點兩端是指針

一個節(jié)點中的key從左到右非遞減排列

所有節(jié)點組成樹結(jié)構(gòu)

每個指針要么為null,要么指向另外一個節(jié)點

一個度為d的B-Tree,設(shè)其索引N個key,則其樹高h的上限為logd((N+1)/2),檢索一個key查找節(jié)點的個數(shù)的漸進復(fù)雜度為logd(N)

更新后的操作

插入刪除新的數(shù)據(jù)記錄會破壞B-Tree的性質(zhì),因此在插入刪除時,需要對樹進行一個分裂、合并、轉(zhuǎn)移等操作以保持B-Tree性質(zhì)

B+樹

bb7b4ebc-3fc2-11ec-9195-dac502259ad0.jpg

每個節(jié)點的指針上限為2d而不是2d+1

內(nèi)節(jié)點不存儲data,只存儲key

葉子節(jié)點不存儲指針

在經(jīng)典B+樹的基礎(chǔ)上,增加了順序訪問指針--》提高區(qū)間訪問的性能

為什么使用B/B+樹?

主存讀取

當(dāng)系統(tǒng)需要讀取主存時,則將地址信號放到地址總線上傳給主存

主存讀到地址信號后,解析信號并定位到指定存儲單元,然后將此存儲單元數(shù)據(jù)放到數(shù)據(jù)總線上,供其它部件讀取

主存存取的時間僅與存取次數(shù)呈線性關(guān)系,因為不存在機械操作,兩次存取的數(shù)據(jù)的“距離”不會對時間有任何影響

磁盤存取原理

磁盤轉(zhuǎn)動,每個磁頭不動,負責(zé)讀取內(nèi)容

不過已經(jīng)有了多磁頭獨立技術(shù)

局部性原理

磁盤預(yù)讀:長度一般以頁的整數(shù)倍為單位

MyISAM索引實現(xiàn)

使用B+樹作為索引結(jié)構(gòu),data存放數(shù)據(jù)記錄的地址

索引文件與數(shù)據(jù)文件分離

主索引和輔助索引(Secondary key)在結(jié)構(gòu)上沒有任何區(qū)別,只是主索引要求key是唯一的,而輔助索引的key可以重復(fù)

非聚集:MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,讀取相應(yīng)數(shù)據(jù)記錄

.MYI文件的組成

整個索引文件的基本信息state

各索引的限制信息base

各索引的定義信息keydef

各索引記錄的概要信息recinfo

讀取索引的流程

query請求,直接讀取key cache中的cache block,有就返回

沒有就到.MYI文件中以file block方式讀取數(shù)據(jù)

再以相同的格式存取key cache

再將key cache中的數(shù)據(jù)返回

InnoDB索引實現(xiàn)

也是使用B+樹

第一個與MyISAM的不同點

第一個重大區(qū)別是InnoDB的數(shù)據(jù)文件本身就是索引文件,表數(shù)據(jù)文件本身就是按B+Tree組織的一個索引結(jié)構(gòu)

InnoDB的數(shù)據(jù)文件本身要按主鍵聚集

所以InnoDB要求表必須有主鍵(MyISAM可以沒有)

沒有顯式指定,自動選擇唯一標(biāo)識列

不存在的話,生成6個字節(jié)長整型的隱含字段

第二個與MyISAM的不同點

InnoDB的輔助索引data域存儲相應(yīng)記錄主鍵的值而不是地址

換句話說,InnoDB的所有輔助索引都引用主鍵作為data域

輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄

得出的優(yōu)化點

不建議使用過長的字段作為主鍵,因為所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大

用非單調(diào)的字段作為主鍵在InnoDB中也不好,因為InnoDB數(shù)據(jù)文件本身是一顆B+Tree,非單調(diào)的主鍵會造成在插入新記錄時數(shù)據(jù)文件為了維持B+Tree的特性而頻繁的分裂調(diào)整,十分低效,而使用自增字段作為主鍵就很不錯了

聚簇索引鍵被更新造成的成本除了索引數(shù)據(jù)可能會移動,相關(guān)的所有記錄數(shù)據(jù)也要移動

索引使用策略及優(yōu)化

全列匹配

按照索引中所有列進行精確匹配(這里精確匹配指“=”或“IN”匹配)時,索引可以被用到

理論上索引對順序是敏感的,但是由于MySQL的查詢優(yōu)化器會自動調(diào)整where子句的條件順序以使用適合的索引

最左前綴匹配

當(dāng)查詢條件精確匹配索引的左邊連續(xù)一個或幾個列時,索引可以被用到

查詢條件用到了索引中列的精確匹配,但是中間某個條件未提供

只能用到索引中,從中間斷開前的列

應(yīng)對

可以增加輔助索引

當(dāng)中間條件選項較少時,用隔離列的方式,使用IN包含

看情況,比較建立

查詢條件沒有指定索引第一列

不滿足使用索引的條件

匹配某列的前綴字符串

可以使用索引

如果通配符%不出現(xiàn)在開頭,則可以用到索引,但根據(jù)具體情況不同可能只會用其中一個前綴

范圍查詢

范圍列可以用到索引(必須是最左前綴),但是范圍列后面的列無法用到索引

同時,索引最多用于一個范圍列,因此如果查詢條件中有兩個范圍列則無法全用到索引

僅用explain可能無法區(qū)分范圍索引和多值匹配

查詢條件中含有函數(shù)/表達式

一般不使用哦

手工算好再代入

索引選擇性與前綴索引

MyISAM與InnoDB基數(shù)統(tǒng)計方式

MyisAM索引的基數(shù)值(Cardinality,show index 命令可以看見)是精確的,InnoDB則是估計值

MyisAM統(tǒng)計信息是保存磁盤中,在alter表或Analyze table操作更新此信息

而InnoDB則是在表第一次打開的時候估計值保存在緩存區(qū)內(nèi)

不建議建立索引的情況

表記錄比較少

索引的選擇性低:不重復(fù)的索引值(也叫基數(shù),Cardinality)與表記錄數(shù)(#T)的比值

前綴索引

用列的前綴代替整個列作為索引key,當(dāng)前綴長度合適時,可以做到既使得前綴索引的選擇性接近全列索引,同時因為索引key變短而減少了索引文件的大小和維護開銷

缺點

不能用于ORDER BY和GROUP BY操作

也不能用于Covering index(即當(dāng)索引本身包含查詢所需全部數(shù)據(jù)時,不再訪問數(shù)據(jù)文件本身)

InnoDB主鍵選擇與插入優(yōu)化

如果沒有特別的需要,請永遠使用一個與業(yè)務(wù)無關(guān)的自增字段作為主鍵

InnoDB使用聚集索引,數(shù)據(jù)記錄本身被存于主索引(一顆B+Tree)的葉子節(jié)點上

這就要求同一個葉子節(jié)點內(nèi)(大小為一個內(nèi)存頁或磁盤頁)的各條數(shù)據(jù)記錄按主鍵順序存放,因此每當(dāng)有一條新的記錄插入時,MySQL會根據(jù)其主鍵將其插入適當(dāng)?shù)墓?jié)點和位置,如果頁面達到裝載因子(InnoDB默認為15/16),則開辟一個新的頁(節(jié)點)

如果使用非自增主鍵,每次插入近似隨機,容易引起數(shù)據(jù)的移動,重新讀目標(biāo)頁面,碎片也多了,雖然也可以用OPTIMIZE TABLE重建優(yōu)化,但麻煩啊

參考資料

圖片來源網(wǎng)絡(luò)

《高性能MySQL》

作者:AnnsShadoW

https://www.cnblogs.com/annsshadow/p/5355090.html

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 磁盤
    +關(guān)注

    關(guān)注

    1

    文章

    362

    瀏覽量

    25154
  • 數(shù)據(jù)庫
    +關(guān)注

    關(guān)注

    7

    文章

    3752

    瀏覽量

    64233
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    798

    瀏覽量

    26399

原文標(biāo)題:對 B+ 樹與索引在 MySQL 中的認識

文章出處:【微信號:DBDevs,微信公眾號:數(shù)據(jù)分析與開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    MATLAB的矩陣索引

    對矩陣進行索引是從矩陣中選擇或修改部分元素的一種方式。MATLAB 有幾種索引樣式,它們不僅功能強大、靈活,而且可讀性強、表現(xiàn)力強。矩陣是 MATLAB 用來組織和分析數(shù)據(jù)的一個核心組件,索引是以可理解的方式有效操作矩陣的關(guān)鍵。
    的頭像 發(fā)表于 09-05 09:28 ?357次閱讀
    MATLAB<b class='flag-5'>中</b>的矩陣<b class='flag-5'>索引</b>

    一文了解MySQL索引機制

    的呢?一起靜下心來,耐心看完這篇文章吧,干貨不啰嗦,相信你一定會有所收獲。 一、索引模型 模型也就是數(shù)據(jù)結(jié)構(gòu),常見的三種模型分別是哈希表、有序數(shù)組和搜索。 了解MySQL的朋友已經(jīng)知道,現(xiàn)在
    的頭像 發(fā)表于 07-25 14:05 ?224次閱讀
    一文了解<b class='flag-5'>MySQL</b><b class='flag-5'>索引</b>機制

    步進電機A+ A-有波形輸出,B+ B-沒有波形是什么原因?

    B+B-沒有,會是什么原因。 A+ ---》AOUT1 A- ---》AOUT2 B+ ---》BOUT1 B- ---》BOUT1
    發(fā)表于 04-18 07:30

    labview 創(chuàng)建mysql 表時 設(shè)置時間 怎么mysql是格式是date 而不是datetime?

    選擇 時間日期 但是mysql是date而不是datetime類型 ,除了sql語句創(chuàng)建表 ,怎么能實現(xiàn)創(chuàng)建表數(shù)據(jù)為datetime類型
    發(fā)表于 02-04 09:46

    查詢SQLmysql內(nèi)部是如何執(zhí)行?

    我們知道mySQL客戶端,輸入一條查詢SQL,然后看到返回查詢的結(jié)果。這條查詢語句 MySQL 內(nèi)部到底是如何執(zhí)行的呢?本文跟大家探討一下哈,我們先來看下
    的頭像 發(fā)表于 01-22 14:53 ?518次閱讀
    查詢SQL<b class='flag-5'>在</b><b class='flag-5'>mysql</b>內(nèi)部是如何執(zhí)行?

    瓦特曼AI視覺企業(yè)先后完成數(shù)億元B輪和B+輪融資

    2023年12月,北京瓦特曼智能科技有限公司(以下簡稱“瓦特曼”或“WATTMAN“)先后完成數(shù)億元B輪和B+輪融資,由中國移動旗下北京移數(shù)字新經(jīng)濟產(chǎn)業(yè)基金、國投證券相繼領(lǐng)投。
    的頭像 發(fā)表于 01-13 14:21 ?1549次閱讀

    導(dǎo)致MySQL索引失效的情況以及相應(yīng)的解決方法

    導(dǎo)致MySQL索引失效的情況以及相應(yīng)的解決方法? MySQL索引的目的是提高查詢效率,但有些情況下索引可能會失效,導(dǎo)致查詢變慢或效果不如預(yù)期
    的頭像 發(fā)表于 12-28 10:01 ?717次閱讀

    Mysql索引是什么東西?索引有哪些特性?索引是如何工作的?

    作為開發(fā)人員,碰到了執(zhí)行時間較長的 sql 時,基本上大家都會說” 加個索引吧”。但是索引是什么東西,索引有哪些特性,下面和大家簡單討論一下。
    的頭像 發(fā)表于 12-24 16:20 ?1134次閱讀
    <b class='flag-5'>Mysql</b><b class='flag-5'>索引</b>是什么東西?<b class='flag-5'>索引</b>有哪些特性?<b class='flag-5'>索引</b>是如何工作的?

    MySQL執(zhí)行過程:如何進行sql 優(yōu)化

    (1)客戶端發(fā)送一條查詢語句到服務(wù)器; (2)服務(wù)器先查詢緩存,如果命中緩存,則立即返回存儲緩存的數(shù)據(jù); (3)未命中緩存后,MySQL 通過關(guān)鍵字將 SQL 語句進行解析,并生成一顆對應(yīng)的解析
    的頭像 發(fā)表于 12-12 10:19 ?374次閱讀
    <b class='flag-5'>MySQL</b>執(zhí)行過程:如何進行sql 優(yōu)化

    mysqldecimal的用法

    MySQL的DECIMAL是用于存儲精確數(shù)值的數(shù)據(jù)類型。DECIMAL可以存儲固定精度和小數(shù)位數(shù)的值。MySQL,DECIMAL數(shù)據(jù)類
    的頭像 發(fā)表于 11-30 10:45 ?999次閱讀

    與二叉的定義

    表示。型結(jié)構(gòu)計算機領(lǐng)域中也得到了廣泛應(yīng)用。 Part1 1.1 的定義 (Tree) 是n(n>=0)n(n>=0) n ( n
    的頭像 發(fā)表于 11-24 15:57 ?1248次閱讀
    <b class='flag-5'>樹</b>與二叉<b class='flag-5'>樹</b>的定義

    mysql的數(shù)據(jù)大于千萬怎么辦

    當(dāng)MySQL的數(shù)據(jù)量達到千萬級別時,為了保證數(shù)據(jù)庫的性能和穩(wěn)定性,需要采取一系列優(yōu)化措施和架構(gòu)設(shè)計。本文中,我將詳細介紹如何應(yīng)對大規(guī)模數(shù)據(jù)的挑戰(zhàn),包括硬件、數(shù)據(jù)庫設(shè)計、索引優(yōu)化、分
    的頭像 發(fā)表于 11-23 14:41 ?1495次閱讀

    MySQL導(dǎo)出的步驟

    MySQL是一種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),用于存儲和管理大量的結(jié)構(gòu)化數(shù)據(jù)。實際應(yīng)用,我們經(jīng)常需要將MySQL數(shù)據(jù)庫的數(shù)據(jù)導(dǎo)出到其他地
    的頭像 發(fā)表于 11-21 10:58 ?739次閱讀

    MySQL增刪改查的例子

    MySQL是一種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它具有強大的數(shù)據(jù)處理和數(shù)據(jù)存儲能力。MySQL,我們可以使用各種命令來進行數(shù)據(jù)的增加、刪除、修改和查詢操作。下面將詳細介紹
    的頭像 發(fā)表于 11-16 15:39 ?703次閱讀

    mysql是一個什么類型的數(shù)據(jù)庫

    強、易于使用和管理。本文中,我們將詳盡、詳實、細致地介紹MySQL的功能、優(yōu)勢、架構(gòu)、語法等方面。 一、MySQL的功能: 數(shù)據(jù)庫管理:MySQL具備創(chuàng)建和管理數(shù)據(jù)庫的能力。它可以創(chuàng)
    的頭像 發(fā)表于 11-16 14:43 ?1646次閱讀