自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

聊聊為什么MySQL索引使用B+樹

數(shù)據(jù)庫 MySQL
mysql的innodb默認會將數(shù)據(jù)文件以及索引文件放在表格空間中,不會為每一個單獨的表保存一份數(shù)據(jù)文件,如果需要單獨保存,那么要將 innodb_file_per_table 設(shè)置為on。

聚簇索引與非聚簇索引

不同的存儲引擎,數(shù)據(jù)文件和索引文件位置是不同的,但是都是在磁盤上而不是內(nèi)存上,根據(jù)索引文件、數(shù)據(jù)文件是否放在一起而有了分類:

聚簇索引:數(shù)據(jù)文件和索引文件放在一起,例如:innodb。

每一個數(shù)據(jù)庫在磁盤上都會有一個對應(yīng)的文件:

進去其中一個文件夾:

這其中:

  • frm:存儲的是表結(jié)構(gòu)。
  • ibd:存儲數(shù)據(jù)文件和索引文件。

注意:mysql的innodb默認會將數(shù)據(jù)文件以及索引文件放在表格空間中,不會為每一個單獨的表保存一份數(shù)據(jù)文件,如果需要單獨保存,那么要將 innodb_file_per_table 設(shè)置為on。

非聚簇索引:數(shù)據(jù)和索引文件各自分開存放,例如:MyISAM

  • frm 存儲表結(jié)構(gòu)。
  • MYI存儲索引數(shù)據(jù)。
  • MYD 存儲實際數(shù)據(jù)。

索引備選存儲結(jié)構(gòu)

  • 哈希表。
  • 二叉樹。
  • B樹。
  • B+樹。

HashMap(散列表)

哈希表可以完成索引的存儲,每次添加索引需要計算指定列的hash值,取模運算后計算出下標,將元素插入下標位,使用場景:等值查詢,但是表格中的數(shù)據(jù)是無序數(shù)據(jù)(范圍查找比較消耗時間,需要進行遍歷操作),在企業(yè)中查詢更多是范圍查詢,不合適.另外,Hashmap作為索引的時候,需要全部加載到內(nèi)存,消耗內(nèi)存空間。于是考慮樹結(jié)構(gòu).

HashMap索引的限制:

  • 哈希索引只包含哈希值和行指針,而不存儲字段值,所以不能使用索引中的值來避免讀取行。
  • 哈希索引數(shù)據(jù)并不是按照索引值順序存儲的,所以也就無法用于排序。
  • 哈希索引也不支持部分索引列匹配查找,因為哈希索引始終是使用索引列的全部內(nèi)容來計算哈希值的。
  • 哈希索引只支持等值比較查詢,包括=、IN()、<>(注意<>和<=>是不同的操作)。也不支持任何范圍查詢,例如WHERE price>100。
  • 訪問哈希索引的數(shù)據(jù)非???,除非有很多哈希沖突(不同的索引列值卻有相同的哈希值)。當出現(xiàn)哈希沖突的時候,存儲引擎必須遍歷鏈表中所有的行指針,逐行進行比較,直到找到所有符合條件的行。
  • 如果哈希沖突很多的話,一些索引維護操作的代價也會很高。例如,如果在某個選擇性很低(哈希沖突很多)的列上建立哈希索引,那么當從表中刪除一行時,存儲引擎需要遍歷對應(yīng)哈希值的鏈表中的每一行,找到并刪除對應(yīng)行的引用,沖突越多,代價越大。

樹的發(fā)展緣由

計算機領(lǐng)域的樹的特點是左子樹小于根節(jié)點,右子樹大于根節(jié)點,從左到右是有序的,多叉樹查找效率比較低,后來有了二叉樹,二叉樹接近二分查找(時間復(fù)雜度),但是會出現(xiàn)下面這種情況,變成了查詢時間復(fù)雜度高的鏈表查詢:

于是有了 平衡樹(AVL樹,要求左右結(jié)點高度差不大于于1),也就是插入數(shù)據(jù)之后,會自旋調(diào)整變成平衡樹,但是旋轉(zhuǎn)會影響插入的性能,也就是如果查詢多但是插入少的話可以用AVL樹,但是插入多的話就不適合,為了優(yōu)化插入的時間復(fù)雜度,產(chǎn)生了紅黑樹,紅黑樹左右子節(jié)點高度差不超過一倍即可(例如左子樹高度4,那么右子樹高度可以是8),但是紅黑樹問題是:由于允許子樹高度差超過一倍,可能出現(xiàn)由于樹的深度過大而造成磁盤IO讀寫過于頻繁,進而導(dǎo)致效率低下的情況。

為什么會出現(xiàn)這樣的情況,我們知道要獲取磁盤上數(shù)據(jù),必須先通過磁盤移動臂移動到數(shù)據(jù)所在的柱面,然后找到指定盤面,接著旋轉(zhuǎn)盤面找到數(shù)據(jù)所在的磁道,最后對數(shù)據(jù)進行讀寫。磁盤IO代價主要花費在查找所需的柱面上,樹的深度過大會造成磁盤IO頻繁讀寫。根據(jù)磁盤查找存取的次數(shù)往往由樹的高度所決定,所以,只要我們通過某種較好的樹結(jié)構(gòu)減少樹的結(jié)構(gòu)盡量減少樹的高度,B樹可以有多個子女,從幾十到上千,可以降低樹的高度。

接下來考慮B樹(B-樹)。

B樹

B樹特點是,結(jié)點(非葉子結(jié)點)有可變數(shù)量的子節(jié)點(事先設(shè)定好),在一個節(jié)點中需要設(shè)置鍵值,因為子節(jié)點數(shù)量有一定的允許范圍,所以B樹不需要像其他自平衡查找樹那樣頻繁地重新保持平衡,B樹示意圖:

B樹特點:

1、所有鍵值分布在整顆樹中。

2、搜索有可能在非葉子結(jié)點結(jié)束,在關(guān)鍵字全集內(nèi)做一次查找,性能逼近二分查找。

3、每個節(jié)點最多擁有m個子樹,最多有m-1個鍵值。

4、根節(jié)點至少有2個子樹。

5、分支節(jié)點至少擁有m/2顆子樹(除根節(jié)點和葉子節(jié)點外都是分支節(jié)點)。

6、所有葉子節(jié)點都在同一層、每個節(jié)點最多可以有m-1個key,并且以升序排列。

B樹鍵值攜帶數(shù)據(jù)

實例圖說明:

每個節(jié)點占用一個磁盤塊,一個節(jié)點上有兩個升序排序的關(guān)鍵字和三個指向子樹根節(jié)點的指針,指針存儲的是子節(jié)點所在磁盤塊的地址。兩個關(guān)鍵詞劃分成的三個范圍域?qū)?yīng)三個指針指向的子樹的數(shù)據(jù)的范圍域。以根節(jié)點為例,關(guān)鍵字為 16 和 34,P1 指針指向的子樹的數(shù)據(jù)范圍為小于 16,P2 指針指向的子樹的數(shù)據(jù)范圍為 16~34,P3 指針指向的子樹的數(shù)據(jù)范圍為大于 34。

查找關(guān)鍵字過程:

1、根據(jù)根節(jié)點找到磁盤塊 1,讀入內(nèi)存?!敬疟P I/O 操作第 1 次】。

2、比較關(guān)鍵字 28 在區(qū)間(16,34),找到磁盤塊 1 的指針 P2。

3、根據(jù) P2 指針找到磁盤塊 3,讀入內(nèi)存?!敬疟P I/O 操作第 2 次】。

4、比較關(guān)鍵字 28 在區(qū)間(25,31),找到磁盤塊 3 的指針 P2。

5、根據(jù) P2 指針找到磁盤塊 8,讀入內(nèi)存?!敬疟P I/O 操作第 3 次】。

6、在磁盤塊 8 中的關(guān)鍵字列表中找到關(guān)鍵字 28。

缺點:

1、每個節(jié)點都有key,同時也包含data,而每個頁存儲空間是有限的,如果data比較大的話會導(dǎo)致每個節(jié)點存儲的key數(shù)量變小

2、當存儲的數(shù)據(jù)量很大的時候會導(dǎo)致深度較大,增大查詢時磁盤io次數(shù),進而影響查詢性能

B+樹

特點:

B+樹與B樹類似,但只有葉節(jié)點存放數(shù)據(jù),其余節(jié)點用來索引,B-樹是每個索引節(jié)點都會有Data域.B-樹/B+樹的特點就是每層節(jié)點數(shù)目非常多,層數(shù)很少,目的就是為了就少磁盤IO次數(shù),B-樹的每個節(jié)點都有data域(指針),這無疑增大了節(jié)點大小,說白了增加了磁盤IO次數(shù)(磁盤IO一次讀出的數(shù)據(jù)量大小是固定的,單個數(shù)據(jù)變大,每次讀出的就少,IO次數(shù)增多,一次IO多耗時),而B+樹除了葉子節(jié)點其它節(jié)點并不存儲數(shù)據(jù),節(jié)點小,磁盤IO次數(shù)就少。這是優(yōu)點之一。

另一個優(yōu)點是: B+樹所有的Data域在葉子節(jié)點,一般來說都會進行一個優(yōu)化,就是將所有的葉子節(jié)點用指針串起來。這樣遍歷葉子節(jié)點就能獲得全部數(shù)據(jù),這樣就能進行區(qū)間訪問啦。在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹不支持這樣的遍歷操作。

圖示:

B+Tree是在BTree的基礎(chǔ)之上做的一種優(yōu)化,變化如下:

1、B+Tree每個節(jié)點可以包含更多的節(jié)點,這個做的原因有兩個,第一個原因是為了降低樹的高度,第二個原因是將數(shù)據(jù)范圍變?yōu)槎鄠€區(qū)間,區(qū)間越多,數(shù)據(jù)檢索越快

2、非葉子節(jié)點存儲key,葉子節(jié)點存儲key和數(shù)據(jù)

3、葉子節(jié)點兩兩指針相互連接(符合磁盤的預(yù)讀特性),順序查詢性能更高

注意:在B+Tree上有兩個頭指針,一個指向根節(jié)點,另一個指向關(guān)鍵字最小的葉子節(jié)點,而且所有葉子節(jié)點(即數(shù)據(jù)節(jié)點)之間是一種鏈式環(huán)結(jié)構(gòu)。因此可以對 B+Tree 進行兩種查找運算:一種是對于主鍵的范圍查找和分頁查找,另一種是從根節(jié)點開始,進行隨機查找。

1、InnoDB是通過B+Tree結(jié)構(gòu)對主鍵創(chuàng)建索引,然后葉子節(jié)點中存儲記錄,如果沒有主鍵,那么會選擇唯一鍵,如果沒有唯一鍵,那么會生成一個6位的row_id來作為主鍵。

2、如果創(chuàng)建索引的鍵是其他字段,那么在葉子節(jié)點中存儲的是該記錄的主鍵,然后再通過主鍵索引找到對應(yīng)的記錄,叫做回表。

責任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2024-05-22 09:01:53

InnoDBB+索引

2019-09-24 09:33:53

MySQLB+樹InnoDB

2019-01-29 19:43:10

MySQL索引數(shù)據(jù)庫

2022-04-16 14:20:29

MySQL數(shù)據(jù)庫

2020-03-19 07:53:56

Mysql引擎B+樹

2019-03-14 09:51:50

MySQL存儲邏輯架構(gòu)

2020-04-01 18:08:57

MySQL B-樹B+樹

2019-08-29 10:46:22

MySQL索引數(shù)據(jù)庫

2020-02-12 19:01:22

索引B-樹B+樹

2021-02-16 16:38:41

MySQLB+樹索引

2023-06-06 09:03:06

InnodbMySQL

2021-05-19 09:51:31

MySQL-B+樹數(shù)據(jù)

2015-04-21 13:09:01

B+樹MySQL索引結(jié)構(gòu)

2021-03-27 11:05:24

數(shù)據(jù)庫索引MySQL

2021-07-04 15:16:14

索引B+數(shù)據(jù)庫

2019-11-05 14:06:07

MySQLB+索引

2019-12-31 09:33:03

MongoDBB 樹NoSQL

2019-11-04 15:00:50

MySQL索引B+樹

2021-04-19 10:03:33

MongoDbB 樹 B+ 樹

2021-11-18 23:08:53

MySQLSQL索引
點贊
收藏

51CTO技術(shù)棧公眾號