mysql索引為啥要選擇B+樹 (下)

有讀者在 mysql索引為啥要選擇B+樹 (上) 上篇文章中留言總結了選擇 B+ 樹的原因,大體上說對了,今天我們再一起來看看具體的原因。

  • 索引為什么要保存在硬盤中

首先要明白幾個概念,服務器存儲一般分內存和硬盤,內存的大小相對于硬盤來說是很小的。內存的訪問速度是納秒級別的,非常快,而硬盤的訪問速度相對內存來說就比較慢了。

不管是訪問內存還是硬盤數據,操作系統都是按數據頁來讀取數據的,即每訪問一次硬盤或內存,只讀取一頁大小的數據,一頁的大小約等于 4 kb,向硬盤讀取數據的操作叫做磁盤 IO。

看到這里你或許會知道了 mysql 索引為啥不保存在內存中了吧,一方面是雖然內存訪問速度快但容量一般都比較小,存不了多少數據,再一個 mysql 需要讓數據持久化,如果服務器斷電或異常重啟會導致數據丟失。

  • 怎么讓二叉搜索樹支持區間查詢

上篇文章中提到過二叉搜索樹,為了讓二叉搜索樹也支持區間查詢,我們把二叉樹的葉子節點通過一個雙向鏈表來連接,并且這個鏈表是有序的,注意葉子節點和普通節點是不一樣的,注意看下面的圖。

因此只需要先找到區間的起始值在鏈表中的位置,然后再往后遍歷,直到遍歷到區間的終止值,即可完成區間查詢。如下圖查找 7-30 這個區間的數據。

  • 如何提升查詢速度

因為二叉搜索樹保存在硬盤中,我們每訪問一個節點,就對應著一次硬盤 IO 操作,上面有說過向硬盤讀取數據速度比較慢。因此樹的高度就代表硬盤 IO 操作的次數,所以我們要想辦法讓樹的高度變矮,來減少硬盤 IO。

要想樹變矮一些,那就把樹多分一些叉來吧,變成一顆多叉樹。下面分別用二叉樹和五叉樹來存儲 16 條數據,看下樹的高度又怎樣的變化。

根節點一般存儲在內存中,普通節點和葉子結點保存在硬盤中,因此顯然二叉樹的高度為 5,需要 5 次硬盤 IO,而五叉樹的高度為 2,查詢一個數據只需要 2 次硬盤 IO。

當然這僅僅是一個小數據的例子,如果有一億條數據,我們構建一個 100 叉樹,這棵樹的高度也只有 3,因此多叉樹能大大降低硬盤 IO,提升查詢速度。

那么問題又來了,對于相同的數據量,是不是構建的多叉樹的叉越多越好呢,因為叉越多樹的高度就會越矮。

上面有說過操作系是按數據頁大小來訪問硬盤的,每次 IO 只讀取一個數據頁大小的數據,如果要讀取的數據大于一個數據頁,則會導致多次 IO。因此我們要盡量讓每個節點的數據大小剛好等于一個數據頁大小,即每訪問一個節點只需一次 IO。

  • 插入和刪除數據怎么辦

上面講的其實都是為了提高查詢性能的,mysql 通常還有插入和刪除操作的,這里我們再簡單說一下 B+ 樹如何處理插入和刪除節點的操作。

這里我們把多叉樹稱作 m 叉樹,這個 m 值是通過數據頁大小和節點數計算出來的,盡量保證每訪問一個節點就是一個數據頁的大小,而且每個節點最多只有 m 個子節點。

現在我們要往數據庫中插入新的數據,即要往 m 叉樹中插入新的節點,這可能就會導致某些節點的子節點個數大于 m,也就會導致該節點大小大于一個數據頁,訪問該節點就需要多次 IO。

為了解決這個問題,m 叉樹會把該節點分裂成兩個節點,然后改分裂操作又會導致其父節點的子節點數可能超過 m,我們再用同樣的方法分裂節點,一直影響到根節點。

刪除操作也是類似的思想,如果有頻繁的刪除節點,就會導致某些節點的子節點過少,就會浪費存儲空間并降低查詢效率。所以就要想辦法讓這些節點合并起來,合并的話就有可能會導致其子節點數超過 m,超過的話就再用上面的分裂方法分裂子節點。

關于節點分裂和合并操作就簡單說這些了,也不畫圖了,知道這個處理思想就好了。

下面再總結一下 B+ 樹:

B+ 樹就是一種多叉樹,是由二叉搜索樹不斷演變過來的,為了滿足區間快速查詢,B+ 樹的葉子節點通過雙向鏈表串聯起來。

這里使用雙向鏈表是為了支持順序和倒序查詢,雖然雙向鏈表相對于單向鏈表雖然會浪費一倍的指針空間,但是在硬盤中這點空間幾乎微乎其微,用這點空間換時間是一件很值得的事情。

B+ 樹的子節點數不超過 m 個,同時也不能少于 m/2 個,一旦超過就需要分裂,一旦少于就需要合并。

關于 mysql InnoDB 引擎為啥要選擇 B+ 樹就寫到這了,文中圖片來源于極客時間《數據結構與算法之美》專欄。對文章如有疑問,歡迎留言交流,如文章有描述不當之處,也希望大家批評指出。如文章對你有幫助,點個贊再走哈,感謝支持。

轉載于:https://juejin.im/post/5c8dce95f265da2da7721946

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/536650.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536650.shtml
英文地址,請注明出處:http://en.pswp.cn/news/536650.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

des加解密java c#,C#編寫DES加密、解密類

這個C#類封裝的DES加密解密,可以使用默認秘鑰進行加密、解密,也可以自定義秘鑰進行加密、解密,調用簡單方便。示例一:using System;using System.Security.Cryptography;using System.Text;namespace DotNet.Utilities{/// /// DE…

八年開發程序員淺析SpringBoot 之 Shiro 與 Redis 多級緩存問題

前言 來自不愿意透露姓名的小師弟的投稿。這篇主要講了,項目中配置了多緩存遇到的坑,以及解決辦法。 發現問題 在一次項目實踐中有實現多級緩存其中有已經包括了 Shiro 的 Cache ,本以為開啟 redis 的緩存是一件很簡單的事情只需要在啟動類上…

Web端H.265播放器研發解密

音視頻編解碼對于前端工程師是一個比較少涉足的領域,涉及到流媒體技術中的文本、圖形、圖像、音頻和視頻多種理論知識的學習,才能夠應用到具體實踐中,本團隊在多媒體領域深耕兩年多,才算是有一定產出,我們自研web播放器…

拳擊 武術java父類,拳擊是一種很有力量的武術類型

原標題:拳擊是一種很有力量的武術類型拳擊是一種很有力量的武術類型,拳擊比賽策略有很多,圍繩技術是其中之一。那么拳擊比賽策略技巧有哪些呢?下面養生之道網為您解析拳擊比賽策略技巧有哪些,看看吧。1、當拳手靠在圍繩…

捧上天的AI落地困難,“ 不懂變通”的華為云如何應付?

前幾年,AI幾乎被捧上天,各大公司傾巢出動,推出了不少吸眼球的應用和產品。如今,這些AI成果是否真得讓企業從中獲得價值?繞不開的數據、隱私和安全問題作何解?不同領域、不同規模、不同技術能力的企業如何最…

Apache-Flink深度解析-DataStream-Connectors之Kafka

Kafka 簡介Apache Kafka是一個分布式發布-訂閱消息傳遞系統。 它最初由LinkedIn公司開發,LinkedIn于2010年貢獻給了Apache基金會并成為頂級開源項目。Kafka用于構建實時數據管道和流式應用程序。它具有水平擴展性、容錯性、極快的速度,目前也得到了廣泛的…

Java使用繼承的語法是,Java基礎語法八 繼承

1、超類和子類超類和子類父類與子類多態:一個對象變量可以指示多種實際類型的現象稱為多態一個變量可以引用父類對象,也可以引用其子類對象,這就是多態。不能將一個超類的引用賦給子類變量,因為調用子類方法時可能發生運行錯誤子類…

kaka 1.0.0 重磅發布,服務于后端的事件領域模型框架。

百度智能云 云生態狂歡季 熱門云產品1折起>>> kaka 1.0.0正式發布了,從三個月前的kaka-notice-lib 1.0.0的發布,經過多次研磨,終于迎來了本次重大更新。 kaka是一款服務于java后端的事件領域模型框架,主要目的為解耦業…

java配置文件工具類,java項目加載配置文件的工具類

java項目加載配置文件的工具類package com.loadproperties;import java.io.IOException;import java.io.InputStream;import java.util.Properties;public class ConfigUtil {private static InputStream input;private volatile Properties configuration new Properties();/…

如何把WAV格式音頻轉換為MP3格式

WAV為微軟公司(Microsoft)開發的一種聲音文件格式,它符合RIFF(Resource Interchange File Format)文件規范,用于保存Windows平臺的音頻信息資源,被Windows平臺及其應用程序所廣泛支持,因此在聲音文件質量和CD相差無幾&…

php 異步處理類,php異步處理類

該類可以請求HTTP和HTTPS協議,還可以處理301、302重定向以及GZIP壓縮等。[PHP]代碼//使用方法require(asynHandle.class.php);$obj new asynHandle();$result $obj->Request(http://baidu.com);$result2 $obj->Get(https://mail.google.com/);echo "{…

惡意軟件盯上了加密貨幣,兩家以色列公司受到攻擊

近日,網絡安全公司Palo Alto Networks威脅研究部門Unit 42發博稱,已確認Cardinal RAT自2017年4月起對兩家從事外匯和加密交易軟件開發的以色列金融科技公司發起過攻擊。 Cardinal RAT是可遠程訪問特洛伊木馬(RAT),攻擊…

php 自定義打印模板下載,PHP – 創建自定義模板系統?

我已經在這里搜索過,令人驚訝的是我找不到答案.我發現了一個類似的線程,但沒有真正的解決方案.復雜的部分是循環,如果我不需要循環我可以只是做一個常規替換.所以,我有一個帶有一些標記的.html文件,如下所示:{{startloop}}{{imgname}}{{endLoop}}我想要做的是用其他…

騰訊財報中“最大秘密”:2018云收入91億元,交首份TO B答卷

騰訊財報中“最大秘密”云業務收入又一次被公開了:2018年,騰訊云收入91億元,增長100%。 3月21日,騰訊發布2018年Q4及全年財報,2018全年收入3126.94億元同比增長32%,凈利潤(Non-GAAP)774.69億元。而被列進“…

根據坐標如何在matlab中l連成曲線,matlab中,如何將兩條曲線畫在一個坐標系里,plot(x1,x2,y1,y2)還是怎樣...

matlab中,如何將兩條曲線畫在一個坐標系里,plot(x1,x2,y1,y2)還是怎樣以下文字資料是由(歷史新知網www.lishixinzhi.com)小編為大家搜集整理后發布的內容,讓我們趕快一起來看一下吧!matlab中,如何將兩條曲線畫在一個坐…

Android 物聯網 傳感器

前幾天做了一個嵌入式課設。將傳感器收集到的數據傳到手機制作的APP里。 項目中涉及到的主要的java代碼和xml布局文件上傳到了github,https://github.com/123JACK123jack/Android轉載于:https://www.cnblogs.com/libin123/p/10578601.html

java已被弱化簽名,高效Java第四十條建議:謹慎設計方法簽名

作用有助于設計易于學習和使用的API。如何做——謹慎地選擇方法的名稱1.選擇易于理解的,并且與同一個包中的其他名稱風格一致的名稱。2.選擇與大眾認可的名稱相一致的名稱。如何做——不要過于追求提供便利的方法每個方法都應該盡其所能。方法太多會使類難以學習、使…

curl有php內存緩存,PHP CURL內存泄露的解決方法

PHP CURL內存泄露的解決方法curl配置平淡無奇,長時間運行發現一個嚴重問題,內存泄露!不論用單線程和多線程都無法避免!是curl訪問https站點的時候有bug!內存泄露可以通過linux的top命令發現,使用php函數mem…

MySQL學習【第五篇SQL語句上】

一.mysql命令 1.連接服務端命令 1.mysql -uroot -p123 -h127.0.0.1 2.mysql -uroot -p123 -S /tmp/mysql.sock 3.mysql -uroot -p123 -hlocalhost 4.mysql -uroot -p123 2.mysql登陸后的一些命令 1.\h或者help   查看幫助 2.\G       格式化查看數據(以k…

phpexcel.php linux,phpexcel在linux系統報錯如何解決

最近有個tp3.2的項目遷移到linux系統上了,突然有天發現原本在win server 2008上運行沒問題的excel導出功能在新的系統上不能使用了。報錯如下:說是1762行有問題,找到這個文件的代碼看看:/*** Get an instance of this class** acc…