成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

分庫分表實戰:尋根問底 — MySQL索引是如何形成的?

數據庫 MySQL
我們知道了MySQL查詢的全過程,也知道了整個過程的瓶頸在于磁盤IO,那怎么降低磁盤IO次數呢?

問題分析:為什么查詢變慢呢?

接上期,我們知道了MySQL查詢的全過程,也知道了整個過程的瓶頸在于磁盤IO,那怎么降低磁盤IO次數呢?

答案就是索引。

正確的使用索引,我們就能有效的把磁盤IO的次數降到常數級,這樣查詢速度將會變得非常快,接下來讓我們深入了解下MySQL的索引。

無索引時,為什么查詢會很慢呢?

在磁盤中,MYSQL存放數據的基本單位是數據頁,數據是放在數據頁中的,每個數據頁中都有很多的數據行,如下圖:

可以看到,在數據頁的數據區中存放著很多數據行,這些數據行就對應數據表中的一行行數據,它們都是通過單向鏈表方式連接組合起來的。

而多個數據頁之間又是通過雙向鏈表的方式連接起來的,如下圖:

而一個數據頁的大小默認為16KB,16KB的大小肯定是不可能放得下一整張表的數據的,所以MYSQL表中的數據,比如我們的訂單表中的訂單數據,會通過這樣雙向鏈表的結構放在多個數據頁中。

如果我們要查詢一條數據的話,就要沿著雙向鏈表一個個去尋找。比如,我們要查詢主鍵為1的那條數據,我們可以從數據頁1開始查詢。

首先,將數據頁1從磁盤中加載到MYSQL內存中,如果發現數據頁1中沒有找到我們想要的那條數據,我們就要沿著雙向鏈表一直尋找下去。

最糟糕的情況,就是我們沿著數據頁1、數據頁2、一直到最后,我們在最后一個數據頁100中才找到我們想要的那條數據,但在這之前,我們得要把數據頁1一直到數據頁100,將這100個數據頁通過磁盤IO加載到內存中,相當于是全表掃描了。

就算MYSQL中有預讀機制存在,可能會預先發生幾次磁盤IO,提前加載一些數據頁到內存中,但這100個數據頁同樣至少會導致幾十次磁盤IO了,而磁盤IO這個過程是很耗費性能的。

MYSQL的索引是如何形成的呢?

那有沒有什么辦法,能夠讓我們盡量快的定位到數據頁,而不至于全表掃描呢?

這件事,就要交給索引來處理了。

順著數據頁的雙向鏈表數據結構一個個去尋找,未免顯得太費力了,我們可以為每個數據頁創建一個目錄,查詢數據時,先到目錄里看一樣有沒有自己想要的數據,這樣不就快很多了嗎。

首先,我們看下數據頁內部的構造:

比如,我們以數據頁1舉例,數據頁1中有很多的數據行,數據行之間都是用指針連接,并且以單向鏈表的方式組織起來的,并且單向鏈表中主鍵一定是保證有序的,無序的數據是沒法創建索引的。

可以看到,數據行前面的 0、2、3 表示記錄的類型,也就是數據行的類型,0表示普通類型,就是表中的一行普通數據,2表示最小記錄,3表示最大記錄,因為我們都知道數據行對應的主鍵都是有順序的。

這里為了方便展示索引,我們假設每個數據頁中都有20條數據,當我們建立索引之后,如下圖:

可以看到,索引頁中會記錄每個數據頁中最小的主鍵即id的值,以及對應的數據頁號,而索引頁就發揮了我們剛提到的數據頁目錄的效果。

索引頁其實也是數據頁,只不過是我們拿來專門存放數據頁的目錄信息而已,可以看到索引頁中的記錄類型,除了2和3之外還有1,1表示的是目錄的類型,因為它是指向具體的某個數據頁的。

而如果數據頁很多的話,一個索引頁中肯定就放不下這些目錄信息,此時,MYSQL會把超出索引頁的目錄信息放到新的索引頁中,然后向上再擴展出一個索引頁,如下圖:

可以看到,數據頁3和數據頁4的目錄信息,被放到了索引頁2中,然后索引3作為擴展出來的索引頁,記錄索引頁1和索引頁2中的最小主鍵值以及索引頁號,也就是說索引頁3中記錄的信息,就相當于更上一層索引的目錄信息了。

如果索引頁3中的容量也不夠了,這個時候,同樣會把超出索引頁3的信息,放到新的一個同層級的索引頁中,然后再向上擴展一層,如下圖:

可以看到,在索引頁3中的信息放不下之后,就會放到索引頁4中,然后向上再拓展一層索引5,索引5中存放的就是索引3和索引4的目錄信息,規律都是一樣的。

而圖片中,我們可以看到,索引頁逐層的往上擴展,看起來就像一棵樹一樣,這也就是我們經常說的B+索引樹,圖片中索引的高度為3層,一般就可以存放千萬級別的數據了。

為什么利用索引查詢就能變快呢?

我們再來看下剛才這張圖:

有了索引之后,如果我們要查詢主鍵為1的那條數據,就可以從B+索引樹最上面的那個索引頁開始查詢。

如圖,我們可以把索引頁5先加載到內存,此時會發生一次磁盤IO,然后再通過二分法,根據主鍵值1,到索引頁5中快速的和各個目錄項中的最小主鍵值對比一下,然后找到下一個索引頁3,通過索引頁3又可以定位到下一個索引頁1。

在這顆B+索引樹中,通過二分法對比最小主鍵值的方式,最終在索引頁1中發現,原來主鍵值為1的那條數據,是位于數據頁1中,此時,我們就可以針對性的把數據頁1加載到內存,然后在內存中就可以查到主鍵為1的數據了。

通過這樣的方式可以發現,我們不需要像之前無索引一樣全表掃描,挨個加載數據頁到內存中,而是利用索引頁,通過高效的二分法查找,很快就可以定位到數據具體是在哪個數據頁中。

并且這個過程中我們也發現,就算是上千萬級別的數據量,我們也可以做到只發生個位數磁盤IO,就可以查詢到數據,這也是為什么用了索引之后查詢的效率明顯提高的原因。

所以,接下來的sql優化,關鍵在于要想辦法讓sql語句能利用索引查數據,這樣的話查詢的效率才會上來,但是有時會有很多因素,導致不能正常讓sql語句使用索引,這也是接下來sql優化的一個關鍵點。

結束語

好了,通過剛才的索引原理,我們知道千萬級的數據量,B+樹基本也就是三到四層,那么如果正常使用到了索引,性能通常不是問題,所以問題原因基本可以確定是因為sql沒有使用到索引,也就是索引失效了。


責任編輯:武曉燕 來源: 石杉的架構筆記
相關推薦

2022-07-03 19:01:19

磁盤IOMySQL

2022-10-13 17:43:10

MySQL存放數據

2021-09-08 09:48:39

數據庫工具技術

2020-11-18 09:39:02

MySQL數據庫SQL

2020-07-28 09:04:09

NewSQL分庫分表

2022-10-10 17:37:59

分庫分表訂單業務

2022-07-11 08:16:47

NewSQL關系數據庫系統

2022-10-11 17:51:49

分庫分表數據庫

2022-07-01 10:37:18

分庫分表數據庫

2020-07-30 17:59:34

分庫分表SQL數據庫

2022-06-30 07:34:46

分庫分表外賣訂單系統

2021-07-28 15:44:52

Java開發數據庫

2019-01-29 19:24:06

分庫分表數據庫

2024-11-22 15:32:19

2018-09-21 15:50:58

數據庫MySQL分庫分表

2019-07-31 09:27:23

數據庫MySQLSQL

2019-11-12 09:54:20

分庫分表數據

2024-07-26 00:16:11

2022-08-02 20:17:13

網絡UnderlayOverlay

2020-11-17 08:08:34

分庫分表
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99爱在线视频 | 亚洲精品久久久蜜桃网站 | 福利视频一区 | 日韩中文av在线 | 日韩在线中文字幕 | 一区网站| 一区二区三区在线 | 欧美中文字幕一区二区 | 91精品国产乱码久久久久久久久 | 久久久久国产精品一区二区 | 在线一区观看 | 亚洲综合电影 | 人人爽人人草 | 中文字幕成人av | 亚洲精品久久久久久久久久久久久 | 欧美日韩亚洲国产综合 | 亚洲一区av | 中文字幕亚洲精品 | 综合自拍| 日韩一区二区在线视频 | 一级片免费视频 | 精品美女 | 亚洲综合大片69999 | www.9191.com | 另类专区成人 | 久久久久久国产精品免费免费 | 国产一区二区三区 | 日韩三级在线 | 国产精品夜色一区二区三区 | 精品一区二区久久久久久久网站 | av色站| 亚洲激情视频在线 | 99爱免费| 午夜寂寞福利视频 | 国产一区二区三区在线 | 久草精品视频 | 天天躁日日躁狠狠躁2018小说 | 亚洲高清av| 精品一区二区三区四区 | av一区二区三区 | 国产精品美女久久久久aⅴ国产馆 |