mysql索引數據結構詳解---mysql詳解(一)

磁盤存取原理

mysql的數據最終是在磁盤的,讀取數據也是從磁盤讀取。
那麼就有必要知道磁盤的工作原理。
如圖所示磁盤的結構圖。
磁盤是逆時針旋轉的,而磁頭只能左右移動。磁頭通過左右移動來劃定磁道,從磁道中獲取數據,數據存儲在各個磁道的扇區中。

如果一個數據表中的數據,存儲在不同的磁道中,那麼就需要多次尋道,耗時就會長。

在這裏插入圖片描述

數據結構

非常直觀,很好用。
數據結構動態演示網站
mysql爲什麼採取BTREE、HASH的數據結構?而沒有采取二叉樹、紅黑樹的數據結構。可以去這樣網站試一下上述數據結構就清楚了。
因爲二叉樹、紅黑樹當數據量大時,都會導致數據深度太大。
Hash我們也很少用,因爲hash對範圍查詢不友好。
BTREE的優點是的mysql的索引基本都是用BTREE。不過mysql的底層用的是B+TREE,比BTREE更高效。

BTREE的度(Degree)-節點的數據存儲個數。存儲個數不能無限大,因爲磁盤每次讀取數據是有限的,比如磁盤每次讀取20kb的數據,而節點存儲了10M的數據,那麼就需要讀取10M/20kb次。一樣會導致效率極低。
磁盤一頁是4kb大小,而i你如果能保證每個B+TREE的節點是4kb大小。這樣就提高了效率。

二叉樹:

在這裏插入圖片描述

紅黑樹:

紅黑樹

B-TREE:

在這裏插入圖片描述
我們提到的查詢磁盤存取原理,我們找磁盤其實是找節點,節點數據會讀取到內存,內存再讀取,內存的速度可以忽略不計。所以BTREE我們查詢0004的話,就是把包含0002、0004的節點讀取到內存。

B+TREE

在這裏插入圖片描述

B-TREE數據存儲方式:

在這裏插入圖片描述

mysql的B+TREE數據存儲方式

在這裏插入圖片描述
B+TREE的指針更方便mysql進行範圍查詢。
B+Tree索引的性能分析:

  • 一 般 使 用 磁 盤 I/ O次 數 評 價 索 引 結 構 的 優 劣
  • 預 讀 : 磁 盤 一 般 會 順 序 向 後 讀 取 一 定 長度的數據(頁的整數倍)放入內存
  • 局 部 性 原 理 : 當 一 個 數 據 坫 用 到 時 , 其 附 近 的 數 據 也 通 常 會 馬 上 被 使 用
  • B+ Tree節 點 的 大小 設 爲 等 於 一 個 頁 , 每 次 新 建 節 點 直 接 中 訪 一 個 頁 的 空 間 , 這 樣 就 保 證 一 個 節 點 物理上也 存 儲 在 一 個 頁 裏 , 就 實 現了一 個 節 點 的 載入只需一 次 I/O
  • B+ Tree的 度 d—般會超過100,因此h非常小(一般爲3到5之間)

mysql存儲引擎

MyISAM和InnoDB。這兩個存儲引擎都是表級別的。

MyISAM

MyISAM存儲引擎存儲方式:
在這裏插入圖片描述
實際上MyISAM的B+TREE不存儲data,而是存儲data的指針。
MyISAM的主鍵索引和非主鍵索引一樣。
題外:如果用UUID作爲表的主鍵,方便數據庫做遷移。

InnoDB

在這裏插入圖片描述
實際上InnoDB的B+TREE存儲了data
InnoDB的主鍵索引和非主鍵索引不一樣。

聯合索引的底層數據結構

字符串類型

如title、name兩個字段均爲字符串類型組成聯合索引,那麼聯合索引的就是title+name這樣加起來作爲一個字符串索引。

多種數據類型組成的聯合索引

如圖所示:第一個爲int類型,第二個爲varchar,第三個爲date。
在這裏插入圖片描述
那麼聯合索引會先用第一索引去比較,第一索引相同再用第二索引比較,第二索引相同再用第三索引去比較。

聯合索引使用情況

注意: mysql的單個索引是聯合索引的特殊情況

create table test(
a int ,
b int,
c int,
d int,
key index_abc(a,b,c)
)engine=InnoDB default charset=utf8;

查詢語句

EXPLAIN
SELECT *
FROM `test` WHERE a='a';--  true
EXPLAIN
SELECT *
FROM `test` WHERE b='b'; -- false
EXPLAIN
SELECT *
FROM `test` WHERE c='c'; -- false
EXPLAIN
  SELECT *
  FROM `test` WHERE a='a' AND b='b'; --  true
EXPLAIN
    SELECT *
    FROM `test` WHERE b='b'  AND a='a';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE a='a'  AND c='c';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE c='c'  AND a='a';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE c='c'  AND b='b';--  false
EXPLAIN
    SELECT *
    FROM `test` WHERE b='b'  AND c='c';--  false
EXPLAIN
    SELECT *
    FROM `test` WHERE a='a'  AND b='b' AND c='c';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE a='a'  AND c='c' AND b='b';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE b='b'  AND c='c' AND a='a';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE b='b'  AND a='a' AND c='c';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE c='c'  AND b='b' AND a='a';--  true
EXPLAIN
    SELECT *
    FROM `test` WHERE c='c'  AND a='a' AND b='b';--  true
EXPLAIN
	select * from test where b<10 and c <10;-- false
EXPLAIN 
	select * from test where a<10 and c <10;-- ture

mysql查詢優化器會判斷糾正這條sql語句該以什麼樣的順序執行效率最高,最後才生成真正的執行計劃。所以,當然是我們能儘量的利用到索引時的查詢順序效率最高,所以mysql查詢優化器會最終以這種順序進行查詢執行。
所以當a字段不在最左時,mysql會自動調整到最左的位置然後再執行。
而根據聯合索引數據結構圖也可以看出,必須有a字段,聯合索引纔會生效。

另外的例子:
在這裏插入圖片描述

劃重點(∩_∩)



本人程序媛一枚,因爲離港澳較近,週末兼職港澳人肉代購。

歡迎各位大佬添加本人微信,還會經常有點贊活動送價值不菲的小禮品哦。

即使現在不需要代購,等以後有了女(男)朋友、有了寶寶就肯定會需要的嘍。

動動手指頭,掃碼一下,就當是對本博文的支持嘛,也是對一個平凡、勤勞、勇敢、秀外慧中等等優點的程序媛莫大的支持哈。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章