前言
前面已經寫了有兩篇章長度的文章,第三篇我一直在尋思着要寫什麼(其實並無),按照腦圖來的話,這篇文章咱們該來說講關於索引的知識了,這但是 MySQL 性能優化很關鍵的知識點,千萬千萬不要錯過,不過我這裏會相對比較深刻地探究,相信你們讀完以後多少會有點收穫。php
先送上兩張飛機票🛬還沒讀過前面文章的夥伴能夠先前往閱讀,由淺入深: MySQL相關(一)- 一條查詢語句是如何執行的 MySQL相關(二)- 一條更新語句是如何執行的html
因爲索引的知識點比較多,官網的內容也不少,若是你們想詳細瞭解能夠到官網,想先通讀了解的話能夠先看看我對索引的總結,這一章節分爲三部分來說:node
- innodb 邏輯存儲結構須要瞭解,做爲番外篇 MySQL相關(番外篇)- innodb 邏輯存儲結構;
- 索引的數據結構也做爲另外的篇章,經過對查詢算法的數據模型進行演算分析 MySQL相關(三)- 索引數據模型推演及 B+Tree 的詳細介紹;
- 對索引的使用及優化規則也會做爲單獨的篇章 MySQL相關(四)- 性能優化關鍵點索引
前面提到的腦圖以下,想要完整高清圖片能夠到微信個人公衆號下【6曦軒】下回復 MySQL 腦圖獲取: mysql
正文
innodb 邏輯存儲結構
https://dev.mysql.com/doc/refman/5.7/en/innodb-disk-management.html https://dev.mysql.com/doc/refman/5.7/en/innodb-file-space.html程序員
MySQL 的存儲結構分爲 5 級:表空間、段、簇、頁、行。面試
表空間 Table Space
上一篇文章講磁盤結構的時候提到過,表空間能夠看作是 InnoDB 存儲引擎邏輯結構的最高層,全部的數據都存放在表空間中。分爲:系統表空間、獨佔表空間、通用表空間、 臨時表空間、Undo 表空間。算法
段 Segment
表空間是由各個段組成的,常見的段有數據段、索引段、回滾段等,段是一個邏輯的概念。一個 ibd 文件(獨立表空間文件)裏面會由不少個段組成。sql
建立一個索引會建立兩個段,一個是索引段:leaf node segment,一個是數據段:non-leaf node segment。索引段管理非葉子節點的數據。數據段管理葉子節點的數據。數據庫
也就是說,一個表的段數,就是索引的個數乘以 2。性能優化
簇 Extent
一個段(Segment)又由不少的簇(也能夠叫區)組成,每一個區的大小是 1MB(64個連續的頁)。
每個段至少會有一個簇,一個段所管理的空間大小是無限的,能夠一直擴展下去,可是擴展的最小單位就是簇。
頁 page
爲了高效管理物理空間,對簇進一步細分,就獲得了頁。簇是由連續的頁(Page)組成的空間,一個簇中有 64 個連續的頁。 (1MB/16KB=64)。這些頁面在物理上和邏輯上都是連續的。
跟大多數數據庫同樣,InnoDB 也有頁的概念(也能夠稱爲塊),每一個頁默認 16KB。
頁是 InnoDB 存儲引擎磁盤管理的最小單位,經過 innodb_page_size 設置。
一個表空間最多擁有 2^32 個頁,默認狀況下一個頁的大小爲 16KB,也就是說一個表空間最多存儲 64TB 的數據。
注意,文件系統中,也有頁的概念。
操做系統和內存打交道,最小的單位是頁 Page。文件系統的內存頁一般是 4K。
SHOW VARIABLES LIKE 'innodb_page_size';
假設一行數據大小是 1K,那麼一個數據頁能夠放 16 行這樣的數據。
舉例:一個頁放 3 行數據。
往表中插入數據時,若是一個頁面已經寫完,產生一個新的葉頁面。若是一個簇的全部的頁面都被用完,會從當前頁面所在段新分配一個簇。
若是數據不是連續的,往已經寫滿的頁中插入數據,會致使葉頁面分裂:
行 Row(僅供瞭解)
InnoDB 存儲引擎是面向行的(row-oriented),也就是說數據的存放按行進行存放。
https://dev.mysql.com/doc/refman/5.7/en/innodb-row-format.html
Antelope[ˈæntɪləʊp](羚羊)是 InnoDB 內置的文件格式,有兩種行格式:
REDUNDANT[rɪˈdʌndənt] Row Format
COMPACT Row Format(5.6 默認)
Barracuda[ˌbærəˈkjuːdə](梭子魚)是 InnoDB Plugin 支持的文件格式,新增了 兩種行格式:
DYNAMIC Row Format(5.7 默認) COMPRESSED Row Format
文件格式 | 行格式 | 描述 |
---|---|---|
Antelope (Innodb-base) | ROW_FORMAT=COMPACT ROW_FORMAT=REDUNDANT | Compact 和 redumdant 的區別在就是在於首部的存 存內容區別。 compact 的存儲格式爲首部爲一個非 NULL 的變長字 段長度列表 redundant 的存儲格式爲首部是一個字段長度偏移 列表(每一個字段佔用的字節長度及其相應的位移)。 在 Antelope 中對於變長字段,低於 768 字節的,不 會進行 overflow page 存儲,某些狀況下會減小結果 集 IO. |
Barracuda (innodb-plugin) | ROW_FORMAT=DYNAMIC ROW_FORMAT=COMPRESSED | 這二者主要是功能上的區別功能上的。 另外在行 裏的變長字段和 Antelope 的區別是隻存 20 個字節, 其它的 overflow page 存儲。 另外這兩都須要開啓 innodb_file_per_table=1 |
innodb_file_format 在配置文件中指定;row_format 則在建立數據表時指定。
show variables like "%innodb_file_format%"; SET GLOBAL innodb_file_format=Barracuda;
在建立表的時候能夠指定行格式。
CREATE TABLE tf1 (c1 INT PRIMARY KEY) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
查看行格式:
SHOW TABLE STATUS LIKE 'student' \G;
這一塊的內容主要是讓你們瞭解頁 page 的概念。 接下來咱們能夠到MySQL相關(三)- 索引數據模型推演及 B+Tree 的詳細介紹查看關於索引數據結構的演算。
By the way
有問題?能夠給我留言或私聊 有收穫?那就順手點個讚唄~
固然,也能夠到個人公衆號下「6曦軒」,
回覆「學習」,便可領取一份 【Java工程師進階架構師的視頻教程】~
回覆「面試」,能夠得到: 【本人嘔心瀝血整理的 Java 面試題】
回覆「MySQL腦圖」,能夠得到 【MySQL 知識點梳理高清腦圖】
我咧,科班出身的程序員,php,Android以及硬件方面都作過,不過最後仍是選擇專一於作 Java,因此有啥問題能夠到公衆號提問討論(技術情感傾訴均可以哈哈哈),看到的話會盡快回復,但願能夠跟你們共同窗習進步,關於服務端架構,Java 核心知識解析,職業生涯,面試總結等文章會不按期堅持推送輸出,歡迎你們關注~~~