MySQL基礎(chǔ)教程之索引的定義與作用
一、索引的定義與核心作用
1. 定義
索引是 MySQL 中用于優(yōu)化查詢效率的數(shù)據(jù)結(jié)構(gòu),類比書籍的“目錄”,無需遍歷全表即可快速定位數(shù)據(jù)位置。
2. 核心作用
提升查詢速度:避免全表掃描(Full Table Scan),減少磁盤 I/O 和 CPU 資源消耗;
優(yōu)化排序/分組:支持 GROUP BY ORDER BY 操作快速完成(無需額外排序);
加速表連接:優(yōu)化 JOIN 操作中關(guān)聯(lián)字段的匹配效率。
二、索引的工作邏輯
當執(zhí)行 SELECT 查詢時,MySQL 執(zhí)行流程如下:
解析查詢語句,識別查詢的表和字段;
檢查該字段是否存在索引:
若有索引:遍歷索引表(數(shù)據(jù)結(jié)構(gòu)如 B+ 樹),快速定位到數(shù)據(jù)記錄行的物理地址,直接讀取數(shù)據(jù);
若無索引:執(zhí)行全表掃描,逐行遍歷表中所有數(shù)據(jù),匹配目標結(jié)果(效率低、資源消耗高)。
三、索引的副作用(不可忽視)
索引并非“越多越好”,存在以下代價:
占用額外磁盤空間:索引表獨立于數(shù)據(jù)表格,會消耗磁盤存儲(如大表的組合索引可能占用大量空間);
增加更新開銷:修改(
INSERT/UPDATE/DELETE)含索引的表時,需同步更新對應(yīng)的索引表(如修改主鍵值時,主鍵索引需重新排序);不合理索引降低效率:如在低選擇性字段創(chuàng)建索引,可能導(dǎo)致 MySQL 放棄使用索引,直接全表掃描。
四、索引的創(chuàng)建依據(jù)(適合/不適合場景)
1. 適合創(chuàng)建索引的場景
主鍵和外鍵:默認創(chuàng)建主鍵索引,外鍵常用于表連接,必須建索引;
大數(shù)據(jù)量表:記錄數(shù)超過 300 行的表,全表掃描代價過高;
高頻查詢字段:WHERE 子句中頻繁出現(xiàn)的字段(如用戶查詢、篩選條件);
連接/排序/分組字段:JOIN 關(guān)聯(lián)字段、GROUP BY/ORDER BY 操作的字段;
高選擇性字段:字段不同值占比高(如身份證號、手機號,選擇性接近 1),索引過濾效果好;
小字段:優(yōu)先在 INT、VARCHAR(短) 等小字段建索引(長文本、BLOB 等大字段索引開銷極高)。
2. 不適合創(chuàng)建索引的場景
低選擇性字段:如性別(男/女)、布爾值(0/1),索引過濾效果差,不如全表掃描;
更新頻繁的字段:如訂單狀態(tài)(高頻更新),索引同步開銷會抵消查詢收益;
小表(<300 行):全表掃描速度快,索引帶來的開銷大于收益;
高頻全表查詢字段:若查詢常使用 SELECT * 且無過濾條件,索引無效。
五、MySQL 常見索引類型及特點
| 索引類型 | 核心特點 | 適用場景 |
|---|---|---|
| 主鍵索引(PRIMARY KEY) | 唯一、非空,一張表僅一個,默認自動創(chuàng)建,底層為聚簇索引(數(shù)據(jù)與索引存儲在一起) | 表的唯一標識(如用戶 ID、訂單 ID) |
| 唯一索引(UNIQUE KEY) | 字段值唯一(允許 NULL 值,僅一個 NULL),避免重復(fù)數(shù)據(jù) | 用戶名、郵箱等需唯一約束的字段 |
| 組合索引(復(fù)合索引) | 基于多個字段創(chuàng)建(如 idx_name_age (name, age)),遵循“最左前綴原則” | 多字段聯(lián)合查詢(如 WHERE name='xxx' AND age=xx) |
| 全文索引(FULLTEXT) | 支持長文本模糊匹配(如文章內(nèi)容、評論),不支持精確查詢 | 博客、新聞等文本內(nèi)容的關(guān)鍵詞搜索 |
補充:組合索引“最左前綴原則”
示例:創(chuàng)建組合索引 idx_a_b_c (a, b, c),僅支持以下查詢場景命中索引:
WHERE a=?(左前綴匹配)WHERE a=? AND b=?(連續(xù)前綴匹配)WHERE a=? AND b=? AND c=?(全匹配)
不命中場景:WHERE b=? WHERE a=? AND c=?(跳過中間字段)。
六、索引與慢查詢的關(guān)聯(lián)
1. 慢查詢與索引的關(guān)系
慢查詢定義:默認情況下,執(zhí)行時間超過 2 秒的 SELECT 語句(可通過 long_query_time 配置修改);
核心原因之一:查詢未使用索引(全表掃描),導(dǎo)致耗時過長;
配置日志記錄:在 /etc/my.cnf 中開啟以下配置,記錄未使用索引的慢查詢:
[mysqld] slow_query_log = 1 # 開啟慢查詢?nèi)罩? slow_query_log_file = /var/lib/mysql/mysql-slow.log # 日志存儲路徑 long_query_time = 2 # 慢查詢閾值(單位:秒) log_queries_not_using_indexes = 1 # 記錄未使用索引的 SQL
配置后需重啟 MySQL 服務(wù)生效。
2. 驗證索引有效性:EXPLAIN工具
作用:分析 SQL 執(zhí)行計劃,查看是否使用索引、索引類型、掃描行數(shù)等;
用法:在查詢語句前加 EXPLAIN,示例:
EXPLAIN SELECT * FROM user WHERE id=1;
關(guān)鍵字段解讀:
type:索引使用類型(ALL表示全表掃描,ref/range/eq_ref表示使用索引);key:實際使用的索引名稱(NULL表示未使用索引);rows:預(yù)估掃描的行數(shù)(值越小,效率越高)。
七、索引底層與優(yōu)化技巧
1. 索引底層數(shù)據(jù)結(jié)構(gòu)(MySQL 默認)
采用 B+ 樹 結(jié)構(gòu),優(yōu)勢:
葉子節(jié)點有序排列,支持范圍查詢(如 BETWEEN IN);
葉子節(jié)點存儲數(shù)據(jù)地址(非聚簇索引)或數(shù)據(jù)本身(聚簇索引),查詢效率穩(wěn)定;
樹高度低(百萬級數(shù)據(jù)僅需 3-4 層),磁盤 I/O 次數(shù)少。
2. 聚簇索引 vs 非聚簇索引
聚簇索引:索引與數(shù)據(jù)存儲在一起(如主鍵索引),查詢無需“回表”,效率最高;
非聚簇索引:索引與數(shù)據(jù)分離,葉子節(jié)點存儲主鍵值,查詢需通過主鍵值二次查找數(shù)據(jù)(回表),效率略低。
3. 索引失效的常見場景(避坑!)
索引字段使用函數(shù)/運算:WHERE SUBSTR(name,1,2)='張'(無法命中 name 索引);
模糊查詢以 % 開頭:WHERE name LIKE '%三'(全模糊 %三% 也失效);
OR 條件中部分字段無索引:WHERE id=1 OR age=20(若 age 無索引,整個查詢可能全表掃描);
隱式類型轉(zhuǎn)換:WHERE phone='123456'(phone 為 INT 類型,字符串與數(shù)字轉(zhuǎn)換導(dǎo)致索引失效);
聯(lián)合查詢中違背最左前綴原則(見組合索引部分)。
4. 索引優(yōu)化技巧
覆蓋索引:查詢字段僅包含索引列(如 SELECT id, name FROM user WHERE id=1,id 為主鍵索引),避免回表;
定期維護索引:刪除冗余索引(如已存在 idx_a_b,無需再建 idx_a)、優(yōu)化碎片索引(OPTIMIZE TABLE 表名);
避免過度索引:一張表索引數(shù)量建議不超過 5 個,過多索引會導(dǎo)致更新變慢。
八、核心小結(jié)
索引核心價值:加速查詢,減少全表掃描開銷;
創(chuàng)建原則:“高頻查詢、高選擇性、小字段”優(yōu)先,避開“更新頻繁、低選擇性”字段;
驗證工具:用
EXPLAIN檢測索引是否生效,結(jié)合慢查詢?nèi)罩緝?yōu)化索引;平衡取舍:索引并非越多越好,需權(quán)衡查詢效率與更新開銷。
到此這篇關(guān)于MySQL基礎(chǔ)教程之索引定義與作用的文章就介紹到這了,更多相關(guān)MySQL索引定義與作用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL?DELETE語句實現(xiàn)安全高效的數(shù)據(jù)刪除策略
數(shù)據(jù)刪除是數(shù)據(jù)庫管理中的高風險操作,需要謹慎處理,本文將全面剖析MySQL?DELETE語句的各種用法、安全注意事項和性能優(yōu)化技巧,希望對大家有所幫助2025-12-12
MySQL數(shù)據(jù)庫實驗實現(xiàn)簡單數(shù)據(jù)庫應(yīng)用系統(tǒng)設(shè)計
這篇文章主要介紹了MySQL數(shù)據(jù)庫實驗實現(xiàn)簡單數(shù)據(jù)庫應(yīng)用系統(tǒng)設(shè)計,文章通過理解并能運用數(shù)據(jù)庫設(shè)計的常見步驟來設(shè)計滿足給定需求的概念模和關(guān)系數(shù)據(jù)模型展開詳情,需要的朋友可以參考一下2022-06-06
如何使用MySQL查詢某個列中相同值的數(shù)量統(tǒng)計
這篇文章的主要內(nèi)容是通過MySQL查詢某個列中相同值的數(shù)量統(tǒng)計,文章簡潔明了,具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-07-07
從數(shù)據(jù)庫中取出最近三十天的數(shù)據(jù)并生成柱狀圖
從數(shù)據(jù)庫中取出最近三十天的數(shù)據(jù)并生成柱狀圖的代碼,需要的朋友可以參考下。2011-05-05
MySql中如何使用 explain 查詢 SQL 的執(zhí)行計劃
explain命令是查看查詢優(yōu)化器如何決定執(zhí)行查詢的主要方法。這篇文章重點給大家介紹MySql中如何使用 explain 查詢 SQL 的執(zhí)行計劃,感興趣的朋友一起看看吧2018-05-05

