MySQL InnoDB索引原理

来源:https://www.cnblogs.com/amos01/archive/2022/08/27/16488759.html
-Advertisement-
Play Games

JDBC 一、JDBC概述 什麼是JDBC? **JDBC 是使用 Java 語言操作關係型資料庫的一套 API。**這套 API 是交由不同的資料庫廠商實現的。我們利用 JDBC 編寫操作資料庫的代碼,真正執行的是各個資料庫的實現類(驅動)。 全稱:(Java DataBase Connectiv ...


 資料庫與I/O原理

數據會持久化到磁碟,查詢數據是就會有I/O操作,相對於緩存操作,I/O操作的時間成本相當高昂。

I/O操作的基本單位是一個磁碟頁面,比如16KB的頁面大小。當數據量比較大時,單表數據就會分佈在多個磁碟頁面。

如果沒有索引,就必須按順序載入磁碟頁面到緩存進行查找,判斷數據是否存在。隨著數據量的增長,磁碟I/O操作的次數也會越來越多。

因此,有必要通過一些輔助的數據結構來提交檢索的速度。

從上面可以看出,想要快速讀取到數據,可從以下幾個方面著手

1. 如何儘量減少磁碟IO操作

2. 如何快速定位到數據所在的磁碟頁面

3. 如何快速定位數據在磁碟頁面內的位置

 

資料庫索引是什麼

索引是存儲引擎用於快速查找記錄的一種數據結構。

舉個類似的例子,當我們要閱讀《高性能MySQL》的第五章時,一般會先查找目錄,找到第五章對應的頁碼,然後翻到對應頁碼即可。

目錄一般不會超過10頁,整本書有將近700頁。

如果沒有目錄,那麼我們只能順序或者使用二分的方法來查找第五章,需要翻頁的次數就會更多。

索引的作用與書籍的目錄相似,用於輔助快速查找目標數據。

 

存儲結構

記錄(行)格式

InnoDB支持四種記錄格式,分別是REDUNDANT、COMPACT、DYNAMIC和COMPRESSED,MySQL5.7預設是DYNAMIC格式。

下圖是DYNAMIC行格式的示意圖

 

記錄頭信息的格式示意圖如下

部分欄位含義

deleted_flag:顧名思義,該記錄是否被刪除的標誌

min_rec_flag:B+樹每層非葉子結點中最小的記錄項的標誌

n_owned: 頁面中分組的

heap_on: 表示當前記錄在頁面堆中的相對記錄

record_type: 表示當前記錄的類型,0表示普通記錄,1表示B+樹非葉子結點的目錄項記錄,2表示Infimum記錄,3表示Supremum記錄。

next_record: 指向下一條記錄,表示下一條記錄的相對位置

 

記錄示例

所有頁面都有兩條虛擬記錄,即Infimum和Supremum。

Infimum代表頁面中的最小的記錄,而Supremum則代表頁面中最大的記錄。

 

數據排序

頁內的記錄串聯成一個單向鏈表。

如果表有主鍵,會根據主鍵排序;

沒主鍵有唯一非空索引,會根據該索引排序;

兩者都沒有,InnoDB會自動生成一個row_id列並根據該列進行排序。

 

格式

頁是InnoDB管理存儲空間的基本單位,一個頁的大小一般是16K。

數據頁面的結構如下圖

File Header:頁面通用信息,如當前頁號、上一頁/下一頁頁號

Page Header:頁面的各種狀態信息,如分組數量,記錄數

User Records:記錄的有序鏈表

Free Space:頁面中尚未使用的空間

Page Directory:對User Records數據進行分組,減少遍歷鏈表的次數,加速查找

File Tailer:校驗頁面數據是否完整

 

數據查找

頁面內的數據是有序的單向鏈表。

假設單行數據128B,而單個磁碟頁面大小可以是16KB,因此一個磁碟頁面最多可以存放128條數據。這樣挨個查找太慢。

可以利用有序鏈表的特性,對有序數據進行分組,記錄每組的最大值,形成一個有序分組列表。先二分查找有序分組列表,再查找分組內的數據。

這裡就會涉及的行記錄的n_owned和頁面的Page Directory了,InnoDB分組規則如下

1. Infimum記錄所在的分組只能有一條記錄

2. Supremum記錄所在的分組擁有的記錄數量為1~8條

3. 其它分組擁有的記錄數量為4~8條

4. 分組指向組內ID最大的行。

 

 

查找過程

下圖是簡化的行記錄和Page Directory。

 

在上圖中查找ID=17的記錄

1. 利用分組進行二分查找,

(1 + 5) / 2 = 3,分組3的最大ID為10,因此繼續在右半區間查找

(3 + 5) / 2 = 4,分組最大的ID為15,17位於右半區間,又應為5 - 4 = 1,因此,17位於分組5

2. 組內順序查找

在分組內遍歷單向鏈表,查找到ID=17的記錄

 

B+樹索引

B+樹數據結構

B樹詳解,這邊隨筆中介紹了B樹的查找、插入、刪除操作,可以深入理解B數的數據結構

 

CREATE TABLE `t_student` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`age` int NOT NULL DEFAULT '0' COMMENT '年齡',
`height` int NOT NULL DEFAULT '0' COMMENT '身高'
 PRIMARY KEY (`id`)
 KEY `age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=COMPACT

 

 

 

聚簇索引

為了方便畫圖表示,下麵是簡化的聚簇索引各種記錄格式

  

聚簇索引結構舉例

 

從上圖可以看出,

1)頁面內記錄按照主鍵增長的順序構成一個單項鏈表

2)對於普通記錄,則是一個按照主鍵有序的雙向鏈表

二級索引

為了方便畫圖表示,下麵是簡化的二級索引各種記錄格式

 

二級索引結構舉例

從上圖可以看出,

1)頁面內記錄按照二級索引age增長的順序構成一個單項鏈表

2)對於普通記錄,則是一個按照age有序的雙向鏈表

3)普通記錄並沒沒有包含完整的信息,而是<age,主鍵>的組合,需要取其它信息如height還需要進行回表

回表: 資料庫根據索引(非主鍵)找到了指定的記錄所在行後,還需要根據索引上保存的主鍵 ID 再次到數據塊里獲取數據。

 

建立索引的原則

1. 儘量使用占用空間少的索引

索引欄位占用空間小,意味著單個頁面可以存放更多的目錄項目記錄,使得B+數更加扁平,從而減少IO次數

2. 選擇頻繁作為查詢條件的欄位作為索引

頻繁作為查詢條件的欄位作為索引,減少查詢的時間,避免全表查詢。

3. 選擇區分度高的欄位作為索引

例如性別隻有男1女2兩種情況,如果建立索引,目錄項只有兩條記錄,意義不大。還增加了維護索引的成本。

4. 最左匹配原則

多個欄位構成聯合索引時,這幾個欄位的順序十分重要。

假設有聯合索引<a,b,c>

目錄項記錄是先按a排序,如果a相等再按b排序,如果a和b都相等,再按c排序。

如果查詢條件只有(b,c),則改索引並不會生效。如果只有(a),那索引只是部分生效。

 

InnoDB Row Formats

《MySQL是怎麼運行的》

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 概述 本文描述幾個WPF的常用特性,包括:樣式、觸發器和控制項模板。 樣式/Style Style就是控制項的外觀,在XAML中,我們通過修改控制項的屬性值來設置它的樣式,如: <!--直接定義style--> <Border Grid.Row="0" Grid.Column="0" Background ...
  • 概述 本文描述幾款WPF中常用的佈局控制項。 Grid Grid是WPF最常用的佈局控制項。 它把面板分割為固定長和寬的網格,子控制項就放置在網格內。 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefini ...
  • WPF是一個生不逢時的技術,剛推出的時候由於機器性能的原因會感覺很卡,等機器性能提高了,WEB時代又來了,做桌面應該的本來就不多了,加上WinForm又比較簡單易用,誰還用WPF呢! 在種情況下寫一個WPF快速開發入門的教程的意義是什麼呢?本教程是針對具備WinForm經驗的.NET開發人員,我希望... ...
  • 操作系統支持多個應用程式同時執行,每個應用至少對應一個進程,彼此之間的操作和數據不受干擾。當一個進程需要磁碟IO的時候,CPU就切換到另外的進程,提高了CPU利用率。有了進程,為什麼還要線程?因為進程的成本太高了。啟動新的進程必須分配獨立的記憶體空間,建立數據表維護它的代碼段、堆棧段和數據段,這是昂貴... ...
  • Linux應急響應-系統日誌排查-溯源 溯源 找到攻擊者。系統日誌分析攻擊者的ip 攻擊者可能留下了一些代碼 樣本 網上的信息很大程度上是不可信的。 方法: 蜜罐 高交互的蜜罐 溯源: ip 日誌分析 (通過日誌分析,分析哪個ip攻擊了目標) 目的:分析黑客在伺服器上做了什麼事情? Linux 應急 ...
  • TMC2209是用於兩相步進電機的超靜音電機驅動器IC。 TMC2209與許多傳統驅動器以及TMC2208引腳相容。 TRINAMICs先進的StealthChop2斬波器可確保電機無噪音運行,實現最高效率和最佳電機扭矩。其快速的電流調節和抑制共振功能組合可實現高動態運動。 StallGuard用於 ...
  • Artlantis studio 2021 for Mac是 Mac 平臺上一款專業的 3D 高級渲染器,artlantis mac版專為設計師和建築師所設計,能夠為您快速創建出 VR 全景,動畫和 3D 透視圖等效果。artlantis 2021憑藉著出色的動畫製作,超凡的質量與渲染,iVisit ...
  • 帝國時代3是一款即時戰略游戲,這次為大家帶來的是帝國時代3三合一完整版,包含了帝國時代III原版、帝國時代III-酋長、帝國時代III-亞洲王朝三個中文版本,向玩家展示了不同民族風格迥異的經濟體制和作戰方式,游戲經過簡化,極易上手,玩家可以選擇在各具特色的歐洲國家中感受新增的城市及卡片技能樹系統,游 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...