MySQL的查找加速器——索引

文章目錄

目錄

前言

一、基礎概念:什么是 MySQL 索引?

二、底層數據結構:為什么 InnoDB 偏愛 B + 樹?

B + 樹的結構特點(以短鏈接表short_link的short_code索引為例):

B + 樹的優勢:

三、索引類型:按功能和結構劃分

1. 按功能劃分(常用類型)

2. 按物理存儲劃分(InnoDB 核心區別)

四、工作原理:索引如何加速查詢?

場景 1:通過short_code查詢長鏈接(SELECT long_url FROM short_link WHERE short_code = 'abc123')

場景 2:查詢 “用戶 123 創建的所有短鏈”(SELECT * FROM short_link WHERE user_id = 123 ORDER BY create_time)

五、優缺點:索引不是 “銀彈”

優點:

缺點:

六、最佳實踐:如何正確使用索引?

1. 適合建索引的場景

2. 不適合建索引的場景

3. 避免索引失效的常見坑

總結


前言

????????MySQL 索引是數據庫性能優化的核心工具,如同書籍的目錄,能幫助數據庫快速定位數據,避免全表掃描。下面從基礎概念、底層結構、類型劃分、工作原理、優缺點及最佳實踐六個維度詳細解析,并結合實際業務場景(如短鏈接平臺、電商系統)說明其應用


一、基礎概念:什么是 MySQL 索引?

索引是 MySQL 在存儲引擎層(如 InnoDB)創建的數據結構,通過對表中特定字段的值進行排序和組織,實現 “快速定位數據位置” 的功能。

  • 核心目標:減少磁盤 I/O 次數(數據庫操作中最耗時的環節),提升查詢效率。
  • 類比:查詢表中short_code = 'abc123'的短鏈接時,無索引需逐行掃描全表;有索引時,可直接通過索引定位到該記錄的物理地址,類似查字典時通過拼音目錄找漢字。

二、底層數據結構:為什么 InnoDB 偏愛 B + 樹?

MySQL 索引的底層數據結構取決于存儲引擎,InnoDB(MySQL 默認引擎)的索引基于B + 樹實現,而非哈希表、二叉樹等,原因是 B + 樹更適合數據庫的讀寫場景。

B + 樹的結構特點(以短鏈接表short_linkshort_code索引為例):
  • 層級化結構:由根節點、非葉子節點、葉子節點組成,層級通常為 3-4 層(百萬級數據僅需 3 次 I/O)。
  • 葉子節點存完整數據(聚簇索引)或主鍵(非聚簇索引)
    • 葉子節點按short_code值有序排列,且通過雙向鏈表連接,支持范圍查詢(如short_code > 'abc' AND short_code < 'def')。
    • 非葉子節點僅存 “索引值 + 子節點指針”,不存實際數據,節省內存空間。
B + 樹的優勢:
  1. 平衡性:左右子樹高度差不超過 1,保證查詢效率穩定(不會出現極端情況下的長路徑)。
  2. 范圍查詢高效:葉子節點的雙向鏈表可快速遍歷連續數據(如查詢 “創建時間在 2023-01-01 到 2023-01-31 的短鏈接”)。
  3. 適配磁盤讀寫:節點大小通常為 16KB(InnoDB 頁大小),單次 I/O 可加載整個節點,減少 I/O 次數。

三、索引類型:按功能和結構劃分

1. 按功能劃分(常用類型)
索引類型定義與特點適用場景(結合業務)
主鍵索引(PRIMARY KEY)表中唯一標識記錄的索引,默認自動創建,字段值非空且唯一,InnoDB 中為主鍵聚簇索引。短鏈接表short_linkid字段(自增主鍵),或short_code(唯一短鏈碼),用于唯一定位單條記錄。
唯一索引(UNIQUE)字段值唯一(允許 NULL,但最多一個 NULL),可避免重復數據。短鏈接表的short_code字段(若不為主鍵),防止生成重復短鏈;用戶表userphone字段,確保手機號唯一。
普通索引(INDEX)無唯一性約束,最常用的索引類型,僅用于加速查詢。短鏈接表的user_id(查詢 “某用戶創建的所有短鏈”)、create_time(按時間篩選短鏈)。
聯合索引(復合索引)對多個字段組合創建的索引,需遵循 “最左前綴原則”(查詢條件需包含最左字段)。電商訂單表order(user_id, create_time)聯合索引,優化 “查詢用戶 A 在 2023 年的所有訂單”。
全文索引(FULLTEXT)用于長文本字段(如varchartext)的關鍵詞檢索,支持自然語言查詢。商品表productdescription字段,實現 “搜索含‘紅酒’關鍵詞的商品”。
2. 按物理存儲劃分(InnoDB 核心區別)
  • 聚簇索引(Clustered Index)
    索引與數據存儲在一起,葉子節點直接存儲完整的行數據(僅 InnoDB 有)。

    • 默認以主鍵為聚簇索引;若表無主鍵,InnoDB 會用唯一索引代替;若均無,則生成隱藏的row_id作為聚簇索引。
    • 例:短鏈接表short_link的主鍵id為聚簇索引,葉子節點存id, short_code, long_url, user_id等完整字段。
  • 非聚簇索引(Secondary Index)
    索引與數據分離,葉子節點僅存儲 “索引值 + 聚簇索引值(主鍵)”,查詢時需先查非聚簇索引得到主鍵,再通過聚簇索引查完整數據(稱為 “回表”)。

    • 例:短鏈接表的user_id普通索引,葉子節點存user_id + id,查詢user_id=123的短鏈詳情時,需先通過user_id索引找到id,再用id查聚簇索引獲取完整數據。

四、工作原理:索引如何加速查詢?

以短鏈接平臺的兩個核心查詢為例,解析索引的工作流程:

場景 1:通過short_code查詢長鏈接(SELECT long_url FROM short_link WHERE short_code = 'abc123'
  1. short_code有唯一索引(非聚簇索引):

    • 數據庫通過 B + 樹查找short_code = 'abc123'的葉子節點,獲取對應的主鍵id = 1001
    • 再通過聚簇索引(主鍵id)查找id = 1001的葉子節點,獲取long_url(回表操作)。
  2. 若查詢字段僅為short_codeidSELECT id, short_code FROM ...):

    • 非聚簇索引的葉子節點已包含short_code + id,無需回表,直接返回結果(稱為 “覆蓋索引”,性能更優)。
場景 2:查詢 “用戶 123 創建的所有短鏈”(SELECT * FROM short_link WHERE user_id = 123 ORDER BY create_time
  • user_id有普通索引,create_time有普通索引:

    • 先通過user_id索引篩選出所有user_id=123的記錄,得到對應的id列表。
    • 再通過聚簇索引獲取每條記錄的完整數據,最后按create_time排序(需額外排序操作)。
  • 若建立(user_id, create_time)聯合索引:

    • 索引葉子節點按user_id排序,同user_id內按create_time排序,篩選后可直接按順序返回,無需額外排序(利用索引的有序性)。

五、優缺點:索引不是 “銀彈”

優點:
  1. 加速查詢:大幅減少掃描行數,百萬級表中查詢耗時可從秒級降至毫秒級。
  2. 優化排序 / 分組:利用索引的有序性,避免ORDER BY/GROUP BY時的文件排序(最耗時的操作之一)。
缺點:
  1. 占用存儲空間:索引需單獨存儲,一張表若有 5 個索引,存儲空間可能比表數據本身還大。
  2. 降低寫入效率:新增 / 修改 / 刪除數據時,需同步更新索引(B + 樹的插入 / 平衡操作耗時),寫入性能可能下降 50% 以上。

六、最佳實踐:如何正確使用索引?

1. 適合建索引的場景
  • 頻繁查詢的字段:如短鏈接表的short_code(每次跳轉都查詢)、用戶表的username(登錄查詢)。
  • 排序 / 分組字段:如訂單表的create_time(按時間統計訂單)、商品表的price(按價格排序)。
  • 聯合查詢條件:如WHERE a = ? AND b = ?,建立(a, b)聯合索引比單字段索引更高效。
2. 不適合建索引的場景
  • 低頻查詢的字段:如 “用戶最后登錄 IP”(半年查一次),建索引浪費空間。
  • 字段值重復率高:如 “性別”(僅男 / 女),索引篩選效率低(幾乎掃描全表)。
  • 大字段:如text類型的 “商品詳情”,索引維護成本極高(字段越長,B + 樹節點存儲的索引值越少,層級越深)。
3. 避免索引失效的常見坑
  • 函數 / 表達式操作索引字段WHERE SUBSTR(short_code, 1, 3) = 'abc'會導致short_code索引失效(索引存原始值,函數處理后無法匹配)。
  • 類型轉換WHERE short_code = 123short_code是字符串)會觸發隱式轉換,索引失效(需寫成WHERE short_code = '123')。
  • 模糊查詢左匹配WHERE short_code LIKE '%abc'(左模糊)索引失效,LIKE 'abc%'(右模糊)可命中索引。
  • 違反最左前綴原則(a, b, c)聯合索引,僅WHERE b = ? AND c = ?無法命中索引(需包含最左字段a)。

總結

????????MySQL 索引是 “以空間換時間” 的典型設計,核心價值是通過 B + 樹等數據結構加速查詢,但需根據業務場景合理設計(如短鏈接的short_code唯一索引、訂單表的聯合索引),避免濫用導致寫入性能下降。理解索引的底層原理和失效場景,是數據庫性能優化的關鍵。

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

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

相關文章

【Vue2手錄11】Vue腳手架(@vue_cli)詳解(環境搭建+項目開發示例)

一、前言&#xff1a;為什么需要 Vue 腳手架&#xff1f; 手動搭建 Vue 項目存在諸多痛點&#xff08;原筆記提及&#xff09;&#xff1a; 依賴管理復雜&#xff1a;需手動下載 Vue、Babel、Webpack 等工具&#xff0c;處理版本兼容性。配置繁瑣&#xff1a;Webpack 配置、E…

自簽發、CA機構簽發、SSH、SCP、RSYNC,SUDO詳解

一、為什么&#xff1f; 1. 自建CA為什么比Lets Encrypt強&#xff1f; 不能把CA放公網&#xff01;Lets Encrypt是給公網服務用的&#xff08;比如10.0.0.30的Web服務&#xff09;&#xff0c;但內網服務&#xff08;比如OpenVPN&#xff09;必須用自簽CA。 CA私鑰必須物理隔…

【Python】Python解決阿里云DataWorks導出數據1萬條限制的問題

【Python】Python解決阿里云DataWorks導出數據1萬條限制的問題一、前言二、腳本功能概述三、核心代碼解析**1. 環境配置與安全設置****2. 用戶配置區****3. 數據清洗函數****4. 核心邏輯**四、完整代碼演示五、總結一、前言 在日常數據分析工作中&#xff0c;團隊經常需要從阿…

計算機網絡(一)基礎概念

本篇文章為計算機網絡相關知識點整理及擴展 基于B站計算機網絡課程&#xff1a;https://www.bilibili.com/video/BV1p69tYZEvN/?spm_id_from333.1007.top_right_bar_window_history.content.click 如有錯誤&#xff0c;還望大家不吝指正 URL&#xff08;統一資源定位符&…

Git的工作區域和文件結構

Git的工作區域和文件結構 1. Git的工作區域2. Git的文件結構 打開.git文件&#xff0c;.git的文件結構如下&#xff1a; objects 存放已經提交的文件&#xff0c;也就是使用 git commit 進行操作后的文件。 index 存放已暫存的文件&#xff0c;也就是使用了 git add 進行操作后…

前端開發易錯易忽略的 HTML 的 lang 屬性

前言本文主要記錄&#xff1a;前端開發中&#xff0c;一個本人錯了好幾年&#xff0c;看似無關緊要的小錯誤&#xff1a;HTML 的 lang 屬性設置。正文HTML 的 lang 屬性在HTML中&#xff0c;lang屬性用于指定文檔的語言。這對于搜索引擎優化&#xff08;SEO&#xff09;、屏幕閱…

【GD32】 GPIO 超詳細總結 (江科大風格課件版)

GD32 GPIO 超詳細總結 (江科大風格課件版)第一部分&#xff1a;GPIO 是什么&#xff1f; 名稱&#xff1a;GPIO General Purpose Input/Output (通用輸入輸出口)作用&#xff1a;MCU與外部世界交互的橋梁。通過程序控制引腳輸出高、低電平&#xff0c;或者讀取引腳的電平狀態。…

《嵌入式硬件(八):基于IMX6ULL的點燈操作》

一、IMX6ULL啟動代碼.global _start_start:ldr pc, _reset_handlerldr pc, _undefine_handlerldr pc, _svc_handlerldr pc, _prefetch_abort_handlerldr pc, _data_abort_handlerldr pc, _reserved_handlerldr pc, _irq_handlerldr pc, _fiq_handler_undefine_handler:ldr pc, …

Spring Boot 調度任務在分布式環境下的坑:任務重復執行與一致性保證

前言在實際業務開發中&#xff0c;調度任務&#xff08;Scheduled Task&#xff09; 扮演著重要角色&#xff0c;例如&#xff1a;定時同步第三方數據&#xff1b;定時清理過期緩存或日志&#xff1b;定時發送消息或報告。Spring Boot 提供了非常方便的 Scheduled 注解&#xf…

剖析ReAct:當大模型學會“邊想邊做”,智能體的進化之路

你是否曾驚嘆于大語言模型&#xff08;LLM&#xff09;強大的推理能力&#xff0c;卻又對其“紙上談兵”、無法真正與世界交互而感到遺憾&#xff1f;你是否好奇&#xff0c;如何讓AI不僅能“說”&#xff0c;更能“做”&#xff0c;并且在做的過程中不斷思考和調整&#xff1f…

小型無人機傳感器仿真模型MATLAB實現方案

一、系統架構設計 無人機傳感器仿真模型需集成多物理場建模與數據融合模塊&#xff0c;典型架構包含&#xff1a; 動力學模型&#xff1a;六自由度剛體運動方程傳感器模型&#xff1a;IMU/GNSS/視覺/氣壓計數學建模數據融合層&#xff1a;卡爾曼濾波/EKF算法實現環境交互模塊&a…

hadoop集群

ssh-keygen -t rsassh-copyid 用戶名遠程服務器地址start-dfs.sh chown [選項] 新所有者[:新所屬組] 目標文件/目錄常用選項&#xff1a;-R&#xff1a;遞歸修改目錄下所有文件和子目錄的所有者&#xff08;處理目錄時常用&#xff09;-v&#xff1a;顯示修改過程的詳細信息-c&…

大模型入門實踐指南

大模型入門教程:從概念到實踐 大模型(Large Language Model, LLM)是當前人工智能領域的核心技術,其本質是通過大規模數據訓練、具備復雜語言理解與生成能力的深度學習模型。本教程將從基礎概念出發,帶你理解大模型的核心邏輯,并通過可直接跑通的代碼示例,快速上手大模型…

貓頭虎開源AI分享:一款CSV to Chat AI工具,上傳CSV文件提問,它可以即時返回統計結果和可視化圖表

貓頭虎開源AI分享&#xff1a;一款CSV to Chat AI工具&#xff0c;上傳CSV文件提問&#xff0c;它可以即時返回統計結果和可視化圖表 摘要 本文將詳細介紹一款開源工具——CSV to Chat AI&#xff0c;它允許用戶上傳CSV文件并通過自然語言提問&#xff0c;系統會即時返回統計…

洛谷P9468 [EGOI 2023] Candy / 糖果題解

[EGOI 2023] Candy / 糖果 思路 NNN 這么小基本就是瞎打的 DP 了。 設 dpi,jdp_{i,j}dpi,j? 為操作 jjj 次后前 iii 項的和最大是多少。 考慮轉移&#xff0c;我們可以枚舉 iii 并考慮將其移動到 ppp 位置&#xff0c;總共操作 kkk 次&#xff0c;那么就有 dpp,kmin?(dpp,…

AI智能體(Agent)大模型入門【3】--基于Chailit客服端實現頁面AI對話

目錄 前言 安裝chailint 創建中文語言環境 創建chailint頁面客戶端 前言 本篇章將會基chailit框架實現頁面進行AI對話。 若沒有自己的本地模型對話&#xff0c;需要查看專欄內的文章&#xff0c;或者點擊鏈接進行學習部署 AI智能體&#xff08;Agent&#xff09;大模型入…

【高并發內存池——項目】定長內存池——開胃小菜

提示&#xff1a;高并發內存池完整項目代碼&#xff0c;在主頁專欄項目中 文章目錄 提示&#xff1a;高并發內存池完整項目代碼&#xff0c;在主頁專欄項目中 先設計一個定長的內存池 一、為什么需要定長內存池&#xff1f; &#x1f3e2; 傳統內存分配的痛點 &#x1f3ed; 內…

6-獲取磁盤分區信息

觀察文件 獲取server端電腦里面存在哪些盤符 int MakeDriveInfo() { //1>A 2>B &#xff08;原本屬于軟盤的 &#xff09;3>C ... 26>Zstd::string result;for (int i 1; i < 26; i) { //讓其循環if (_chdrive(i) 0) //改變當前的驅動,_chdrive函數(c和c中)應…

每天認識一個電子器件之LED燈

LED選型核心參數一覽表參數類別關鍵參數說明 & 為什么重要基本電氣參數正向電壓 (Vf)LED正常發光時兩端的電壓降。必須匹配您的電路電壓。紅/黃光約1.8-2.2V&#xff0c;藍/綠/白光約2.8-3.6V。正向電流 (If)LED正常發光時所需的電流。決定了LED的亮度&#xff0c;必須用電…

Spring Boot 集成 Flowable 7.1.0 完整教程

一、引言 在企業級應用開發中&#xff0c;工作流管理是不可或缺的一部分。從簡單的請假審批到復雜的業務流程&#xff0c;工作流引擎能夠顯著提升系統的靈活性和可維護性。??Flowable?? 作為一個輕量級、基于 Java 的開源工作流引擎&#xff0c;完美支持 ??BPMN 2.0??…