MYSQL 索引與數據結構筆記

MYSQL 索引與數據結構筆記


文章目錄

  • MYSQL 索引與數據結構筆記
    • 1. B-Tree 與 B+ Tree 基礎對比
      • 一、B 樹的優勢
      • 二、B 樹的進一步優化
      • 三、綜合對比
      • 結論
    • 2. MySQL 為何選擇 B+ Tree
    • 3. 索引使用示例與性能分析
      • 3.1 整數字段索引查詢
      • 3.2 字符字段索引查詢
    • 4. 索引失效與類型轉換陷阱
    • 5. 小結


1. B-Tree 與 B+ Tree 基礎對比

  • B-Tree(平衡樹)
    • 每個節點既存儲 (Key),也存儲 實際數據(Data)。
    • 查找時從根節點(Root)開始,沿著指針遍歷至葉節點(Leaf),每次節點訪問都可能觸發一次磁盤 I/O。
    • 特點:小的鍵在左,大的鍵在右,定位單條記錄的最壞深度與樹高成正比。
  • B+ Tree(平衡樹加強版)
    • 非葉子節點 只存儲 ,不存儲數據;所有數據集中存放于 葉子節點
    • 葉子節點之間通過雙向鏈表相連,支持范圍查詢時從起始葉節點依次遍歷,無需回到根節點重復搜索。
    • 由于非葉子節點僅存鍵,可在同頁面存儲更多索引,樹更“寬”、高度更淺,減少索引查找的磁盤 I/O 次數。

以上圖示直觀對比了兩者的結構差異:

  • B-Tree 左側,內外節點均存數據;
  • B+ Tree 右側,內部節點只有鍵,葉子通過鏈表橫向連接。

B 樹相比其他數據結構為何更快?B 樹又如何進一步提升性能?


一、B 樹的優勢

  1. 高扇出(Fan-out)、低高度
    • B 樹的每個節點(頁面)可以包含 m 個子指針和 m–1 個關鍵字,通常 m 很大(幾百到上千),因為頁面大小(如 16 KB)可容納大量記錄指針。
    • 相比二叉搜索樹(每節點僅 2 個子指針),B 樹樹高明顯更低:
      高度 ≈ log ? m N ? log ? 2 N \text{高度} \approx \log_{m}N \ll \log_{2}N 高度logm?N?log2?N
    • 結果:每次查詢只需少量層次的磁盤 I/O。
  2. 磁盤友好:“頁面+批量讀寫”
    • 節點大小與磁盤塊(頁面)大小匹配,一次 I/O 就能讀取或寫入一個完整節點。
    • 大量連續指針和鍵值在同一頁面中,最大化單次 I/O 的有效數據利用率。
  3. 動態平衡
    • B 樹在插入/刪除時始終保持平衡,無需昂貴的旋轉操作(區別于 AVL、紅黑樹)。
    • 分裂/合并操作較少,且都局限在少數相鄰節點,引發的頁面寫回有限。
  4. 支持范圍查詢(部分)
    • 雖非鏈表連接,B 樹也能通過中序遍歷葉子節點進行范圍掃描,復雜度 O ( log ? m N + K ) O(\log_m N + K) O(logm?N+K),其中 K 是返回行數。

二、B 樹的進一步優化

在 B 樹基礎上,B+ 樹對 I/O 和范圍查詢做了兩點關鍵改進:

  1. 非葉子節點只存“路由鍵”
    • B 樹:每個節點都存鍵+數據指針。
    • B+ 樹
      • 內部節點:僅存 和子指針,頁內可容納更多分支,進一步提升扇出 m m m
      • 葉子節點:存所有 鍵 + 數據指針
    • 好處:更寬的樹 → 更淺的樹 → 更少層級 I/O。
  2. 葉子節點雙向鏈表
    • 所有葉子通過指針串聯,形成線性鏈表。
    • 范圍查詢
      1. 定位首條記錄( log ? m N \log_m N logm?N 次 I/O)。
      2. 順鏈遍歷后續葉子頁,每頁一次 I/O,即可連續獲取大量記錄,無需再回到根節點。
    • 預取優化:操作系統或 InnoDB 可預測地提前讀取下幾頁,減少讀取延遲。

三、綜合對比

特性二叉樹 / AVL / 紅黑樹B 樹B+ 樹
樹高 Θ ( log ? 2 N ) \Theta(\log_2 N) Θ(log2?N) Θ ( log ? m N ) \Theta(\log_m N) Θ(logm?N) Θ ( log ? m N ) \Theta(\log_m N) Θ(logm?N)(更小)
每層 I/O1 個節點(小)1 個大頁面1 個更大分支數大頁面
插入/刪除旋轉、重染色開銷大分裂/合并局部節點同 B 樹,節點更少分裂
范圍查詢需要中序多次回溯葉子遍歷可中序,但無鏈表需回根首查后鏈表順序遍歷,高效順序讀取
磁盤利用率無頁面概念,非批量 I/O每頁批量同 B 樹,更多指針→更高頁面利用率

結論

  • B 樹 相比純內存二叉結構,更貼合磁盤 I/O 模型:高扇出、低樹高、少 I/O。
  • B+ 樹 在此基礎上:
    • 更高扇出(節點更“瘦”),進一步壓低樹高;
    • 鏈表化葉子,極大優化范圍掃描和預取,減少隨即 I/O。

這種設計正好契合數據庫對“大量數據+高并發讀寫+范圍查詢”場景的需求,因而被廣泛采用,MySQL InnoDB 默認索引即基于 B+ 樹。


2. MySQL 為何選擇 B+ Tree

  1. 更少的磁盤 I/O

    • 葉子節點更集中,樹高度更低。
    • 訪問任意數據最多經過 ? log ? m N ? \lceil \log_{m}N\rceil ?logm?N?層,且每層頁面能存更多指針。
  2. 高效的范圍查詢

    • 雙向鏈表鏈通所有葉節點。
    • 查詢 [low, high] 時,從根定位 low,再順鏈查到 high,無需多次回根。
  3. 頁面利用更高

    • 非葉子節點僅存鍵,單頁指針更多。
    • 更少分裂、重平衡次數,維護成本更低。

3. 索引使用示例與性能分析

假設有如下測試表:

CREATE TABLE t_demo (id_int INT NOT NULL PRIMARY KEY,id_char CHAR(10),INDEX idx_char (id_char)
);

INDEX / KEY

  • 在 SQL 標準中,INDEX 用于指示“給某列建立額外的索引結構”;MySQL 中 INDEXKEY 同義。
  • 作用:加速基于該列的查找(=IN)、排序(ORDER BY)、范圍掃描(BETWEEN><)等操作。
  • 類型
    • 普通索引(Secondary Index):如上例 idx_char,只存列值 + 聚簇主鍵,用于輔助查找。
    • 唯一索引(UNIQUE INDEX):加上 UNIQUE 關鍵字,保證列值不重復。
    • 全文索引(FULLTEXT):用于自然語言全文檢索。
    • 空間索引(SPATIAL):針對 GIS 數據。

idx_char

  • 這是索引的名字,必須在同表內唯一。

  • 建議命名習慣:idx_<列名>idx_<表名>_<列名>,便于維護和閱讀。

  • 用途示例:

    SHOW INDEX FROM t_demo;
    -- 你會看到一個名為 idx_char 的索引,Column_name: id_char
    DROP INDEX idx_char ON t_demo;
    

聚簇索引 vs 輔助索引

  • 聚簇索引(Clustered Index)
    • 由 InnoDB 強制由主鍵構建。
    • 葉子節點直接存放整行數據(行記錄)。
  • 輔助索引(Secondary Index)
    • 葉子節點只存「索引列值 + 主鍵列值」。
    • 查到主鍵后,再回聚簇索引查整行。

3.1 整數字段索引查詢

EXPLAIN SELECT * FROM t_demo WHERE id_int = 3;
  • Output: key: PRIMARY, rows: 1
  • 利用聚簇索引,直接定位葉節點,一個 I/O 即可返回數據。
  • EXPLAIN 用于讓 MySQL 優化器輸出該查詢的“執行計劃”,常見字段:
列名含義
id查詢標識,表示第幾條子查詢或聯合查詢
select_type查詢類型,如 SIMPLE(簡單查詢)、PRIMARY、SUBQUERY 等
table本行描述的是哪張表
type訪問類型,從好到差:system / const / eq_ref / ref / range / ALL
possible_keys優化器認為可用的索引列表
key實際使用的索引
key_len使用索引的字節長度
ref哪個列或常量與索引列比較
rows估算需要掃描的行數
filtered估算有多少百分比的行會被 WHERE 過濾
Extra額外信息,如 Using index(覆蓋索引)、Using filesortUsing temporary

image-20250510134526863


3.2 字符字段索引查詢

EXPLAIN SELECT * FROM t_demo WHERE id_char = 'three';
  • Output: key: idx_char, rows: 1
  • 較整型略慢,但依然通過二分定位葉節點和鏈表讀取。

image-20250510134511956


4. 索引失效與類型轉換陷阱

當對 索引字段 應用函數或運算時,會導致 MySQL 無法利用索引,轉而全表掃描,示例如下:

EXPLAIN SELECT * FROM t_demo WHERE id_int + 0 = 1;
-- key: NULL, rows: 全表掃描

image-20250510134458178

原因:

  • 聚簇索引的頁內順序被打亂,MySQL 無法在葉節點上直接比較。
  • 索引失效后,每行先轉換再比較,磁盤 I/O 和 CPU 轉換開銷劇增。

最佳實踐

  • 避免在 WHERE 條件中對索引列進行任何運算或類型轉換。

  • 如需偏移量查詢,可將常量移至列右側:

    -- 建議
    SELECT * FROM t_demo WHERE id_int = 1 - 0;
    -- 避免
    SELECT * FROM t_demo WHERE id_int + 0 = 1;
    
  • 對于范圍查詢(如 BETWEEN><),只要不對字段本身改動,即可走范圍索引。

image-20250510134440298


5. 小結

  • B+ Tree:MySQL 默認索引結構,專為大規模數據檢索優化。
  • 范圍查詢:鏈表加速,極大提升大數據下的連續掃描性能。
  • 索引失效:對索引列的任何計算或類型轉換都會導致全表掃描,嚴重影響性能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82796.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

電路中的DGND、GROUND、GROUND_REF的區別,VREF、VCC、VDD、VEE和VSS的區別?

目錄 1 DGND、GROUND、GROUND_REF的區別 1.1 DGND&#xff08;Digital Ground&#xff09; 1.2 GROUND&#xff08;Ground&#xff09; 1.3 GROUND_REF&#xff08;Ground Reference&#xff09; 1.4 區別 2 VREF、VCC、VDD、VEE和VSS的區別 2.1 VREF&#xff08;Refere…

OpenHarmony平臺驅動開發(十),MMC

OpenHarmony平臺驅動開發&#xff08;十&#xff09; MMC 概述 功能簡介 MMC&#xff08;MultiMedia Card&#xff09;即多媒體卡&#xff0c;是一種用于固態非易失性存儲的小體積大容量的快閃存儲卡。 MMC后續泛指一個接口協定&#xff08;一種卡式&#xff09;&#xff0…

C++ 的 VS 項目中引入跨平臺包管理工具 conan

我們知道 C 不像很多其他語言有包管理工具&#xff0c;比如 Python 有 pip&#xff0c;Java 有 maven&#xff0c;C# 有 nuget&#xff0c;JS 有 npm&#xff0c;Go 有 go mod&#xff0c;Rust 有 cargo&#xff0c;項目中需要自己手動引入第三方庫&#xff0c;手動維護帶來了很…

vscode 默認環境路徑

1.下面放在項目根目錄上&#xff1a; .vscode/settings.json 2.settings.json內容&#xff1a; {"python.analysis.extraPaths": ["${workspaceFolder}"],"python.defaultInterpreterPath": "/shared_disk/users/lbg/envs/py310_see3d/b…

Android 項目中配置了多個 maven 倉庫,但依賴還是下載失敗,除了使用代理,還有其他方法嗎?

文章目錄 前言解決方案gradlemaven 倉庫 前言 我們在Android 開發的過程中&#xff0c;經常會遇到三方依賴下載不下來的問題。一般情況下我們會在項目的build.gradle文件中配置多個 maven 倉庫來解決。 // Top-level build file where you can add configuration options com…

uni-app 引入vconsole web端正常,安卓端報錯 Cannot read property ‘sendBeacon‘ of undefined

reportJSException >>>> exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught TypeError: Cannot read property sendBeacon of undefined vconsole 只支持 web 端&#xff0c;…

火山RTC 7 獲得遠端裸數據

一、獲得遠端裸數據 1、獲得h264數據 1&#xff09;、遠端編碼后視頻數據監測器 /*** locale zh* type callback* region 視頻管理* brief 遠端編碼后視頻數據監測器<br>* 注意&#xff1a;回調函數是在 SDK 內部線程&#xff08;非 UI 線程&#xff09;同步拋出來的&a…

web 自動化之 Unittest 四大組件

文章目錄 一、如何開展自動化測試1、項目需求分析&#xff0c;了解業務需求 web 功能納入自動化測試2、選擇何種方式實現自動化測試 二、Unittest 框架三、TestCase 測試用例四、TestFixture 測試夾具 執行測試用例前的前置操作及后置操作五、TestSuite 測試套件 & TestLoa…

42、在.NET 中能夠將?靜態的?法覆寫成靜態?法嗎?

在.NET中&#xff0c;不能將非靜態方法&#xff08;實例方法&#xff09;直接覆寫&#xff08;Override&#xff09;為靜態方法&#xff08;Static Method&#xff09;。以下是關鍵原因和解釋&#xff1a; 1. 方法綁定的本質區別 實例方法&#xff1a;屬于對象的實例&#xf…

8天Python從入門到精通【itheima】-1~5

目錄 1節&#xff1a; 1.Python的優勢&#xff1a; 2.Python的獨具優勢的特點&#xff1a; 2節-初識Python&#xff1a; 1.Python的起源 2.Python廣泛的適用面&#xff1a; 3節-什么是編程語言&#xff1a; 1.編程語言的作用&#xff1a; 2.編程語言的好處&#xff1a;…

3D迷宮探險:偽3D渲染與運動控制的數學重構

目錄 3D迷宮探險:偽3D渲染與運動控制的數學重構引言第一章 偽3D渲染引擎1.1 射線投射原理1.2 紋理透視校正第二章 迷宮生成算法2.1 圖論生成模型2.2 復雜度控制第三章 第一人稱控制3.1 運動微分方程3.2 鼠標視角控制第四章 碰撞檢測優化4.1 層級檢測體系4.2 滑動響應算法第五章…

mac一鍵安裝gpt-sovit教程中,homebrew卡住不動的問題

mac一鍵安裝gpt-sovit教程 僅作為安裝過程中解決homebrew卡住問題的記錄 資源地址 https://www.yuque.com/baicaigongchang1145haoyuangong/ib3g1e/znoph9dtetg437xb#mlAoP 下載一鍵包 下載后并解壓&#xff0c;找到install for mac.sh&#xff0c;終端執行bash空格拖拽in…

git 遠程倉庫管理詳解

Git 的遠程倉庫管理是多人協作和代碼共享的核心功能。以下是 Git 遠程倉庫管理的詳細說明&#xff0c;包括常用操作、命令和最佳實踐。 1. 什么是遠程倉庫&#xff1f; 遠程倉庫&#xff08;Remote Repository&#xff09;&#xff1a;存儲在網絡服務器上的 Git 倉庫&#xff0…

【超詳細教程】安卓模擬器如何添加本地文件?音樂/照片/視頻一鍵導入!

作為一名安卓開發者或手游愛好者&#xff0c;安卓模擬器是我們日常工作和娛樂的重要工具。但很多新手在使用過程中常常遇到一個共同問題&#xff1a;**如何將電腦本地的音樂、照片、視頻等文件導入到安卓模擬器中&#xff1f;**今天&#xff0c;我將為大家帶來一份全網最詳細的…

使用vite重構vue-cli的vue3項目

一、修改依賴 首先修改 package.json&#xff0c;修改啟動方式與相應依賴 移除vue-cli并下載vite相關依賴&#xff0c;注意一些peerDependency如fast-glob需要手動下載 # 移除 vue-cli 相關依賴 npm remove vue/cli-plugin-babel vue/cli-plugin-eslint vue/cli-plugin-rout…

uniapp|實現手機通訊錄、首字母快捷導航功能、多端兼容(H5、微信小程序、APP)

基于uniapp實現帶首字母快捷導航的通訊錄功能,通過拼音轉換庫實現漢字姓名首字母提取與分類,結合uniapp的scroll-view組件與pageScrollTo API完成滾動定位交互,并引入uni-indexed-list插件優化索引欄性能。 目錄 核心功能實現動態索引欄生成?聯系人列表渲染?滾動定位聯動性…

C#中SetProperty方法使用

SetProperty 是 MVVM&#xff08;Model-View-ViewModel&#xff09; 模式中用于實現 屬性變更通知&#xff08;INotifyPropertyChanged&#xff09; 的核心方法&#xff0c;主要用于在屬性值變化時自動更新 UI 綁定。 1. SetProperty 的基本作用 更新字段值&#xff1a;修改屬性…

MYSQL 全量,增量備份與恢復

目錄 一 數據備份的重要性 1 數據備份的重要性 2 數據庫備份類型 2.1 從物理與邏輯的角度分類 2.2. 從數據庫的備份策略角度分類從數據庫的備份策略角度,數據庫的備份可分為完全備份、差異備份和增量備份。 3 常見的備份方法 3.1 物理冷備份 物理冷備份時需要在數據庫處…

豆瓣電影Top250數據工程實踐:從爬蟲到智能存儲的技術演進(含完整代碼)

目錄 引言:當豆瓣榜單遇見大數據技術 項目文檔 1.1 選題背景 1.2 項目目標 2. 項目概述 2.1 系統架構設計 2.2 技術選型 2.3 項目環境搭建 2.3.1 基礎環境準備 2.3.2 爬蟲環境配置 2.3.3 Docker安裝ES連接Kibana 安裝IK插件 2.3.4 vscode依賴服務安裝 3. 核心模…

深度 |國產操作系統“破繭而出”:鴻蒙電腦填補自主生態空白

真心為國內能有像華為這樣的技術型公司而自豪&#xff0c;一步步突圍技術封鎖。從這篇信息&#xff0c;可以給軟件從業者一個啟示&#xff1a;鴻蒙生態將是一個新的機會&#xff0c;值得好好把握。 鴻蒙電腦正成為中國電子信息技術新坐標。 超10億鴻蒙生態設備、2800家鴻蒙智…