MySQL有5種索引類(lèi)型及其特點(diǎn)詳解
前言
MySQL(尤其是 InnoDB 引擎)支持多種索引類(lèi)型,不同索引適用于不同場(chǎng)景。以下是 MySQL 中常見(jiàn)的索引類(lèi)型及其特點(diǎn),按邏輯分類(lèi)和物理結(jié)構(gòu)兩個(gè)維度說(shuō)明:
一、按邏輯用途分類(lèi)(常用)
1.主鍵索引(Primary Key)
- 唯一且非空,一張表只能有一個(gè)。
- InnoDB 中,主鍵索引就是 聚簇索引(Clustered Index):數(shù)據(jù)行與索引存儲(chǔ)在一起。
- 選擇原則:盡量使用自增整數(shù)(避免頁(yè)分裂),避免使用 UUID(隨機(jī)寫(xiě)性能差)。
2.唯一索引(Unique Index)
- 索引列的值必須唯一,但允許有
NULL(多個(gè) NULL 不沖突)。 - 適用于:手機(jī)號(hào)、訂單號(hào)、用戶 ID 等業(yè)務(wù)唯一字段。
- 創(chuàng)建方式:
CREATE UNIQUE INDEX idx_user_phone ON users(phone);
3.普通索引(Secondary Index / Normal Index)
- 最基礎(chǔ)的索引類(lèi)型,允許重復(fù)值、允許 NULL。
- 用于加速
WHERE、JOIN、ORDER BY等查詢。 - 示例:
CREATE INDEX idx_order_status ON orders(status);
4.組合索引(Composite Index / 聯(lián)合索引)
- 對(duì)多個(gè)列創(chuàng)建一個(gè)索引,如
(col1, col2, col3)。 - 遵循 最左前綴原則(Leftmost Prefix Rule):
- 查詢條件必須從最左列開(kāi)始,才能命中索引。
- 例如:索引
(a, b, c)可用于WHERE a=1、WHERE a=1 AND b=2,但不能用于WHERE b=2。
- 建議:把區(qū)分度高(選擇性好)的列放前面。
5.前綴索引(Prefix Index)
- 對(duì)長(zhǎng)字符串字段(如
VARCHAR(255))只索引前 N 個(gè)字符。 - 減少索引大小,提升性能。
- 示例:
CREATE INDEX idx_email_prefix ON users(email(20)); -- 只索引前20字符
- ?? 注意:前綴長(zhǎng)度需通過(guò)
SELECT COUNT(DISTINCT LEFT(email, N)) / COUNT(*)估算區(qū)分度。
二、按物理結(jié)構(gòu)分類(lèi)(InnoDB)
1.聚簇索引(Clustered Index)
- 數(shù)據(jù)即索引:葉子節(jié)點(diǎn)存儲(chǔ)完整的數(shù)據(jù)行。
- InnoDB 自動(dòng)使用主鍵作為聚簇索引;若無(wú)主鍵,則選擇第一個(gè)唯一非空索引;否則用隱藏的
row_id。 - 優(yōu)點(diǎn):主鍵查詢極快(一次 I/O)。
- 缺點(diǎn):二級(jí)索引需“回表”(先查二級(jí)索引 → 再查聚簇索引)。
2.二級(jí)索引(Secondary Index)
- 葉子節(jié)點(diǎn)存儲(chǔ)的是主鍵值,不是完整數(shù)據(jù)。
- 查詢流程:二級(jí)索引 → 主鍵值 → 聚簇索引 → 獲取數(shù)據(jù)(回表)。
- 優(yōu)化回表:使用 覆蓋索引(Covering Index),即查詢字段全部包含在索引中,無(wú)需回表。
三、特殊索引類(lèi)型(特定場(chǎng)景)
1.全文索引(Full-Text Index)
- 用于
TEXT或VARCHAR字段的全文搜索(如文章內(nèi)容搜索)。 - 支持
MATCH() AGAINST語(yǔ)法。 - InnoDB 從 MySQL 5.6 開(kāi)始支持。
- 示例:
CREATE FULLTEXT INDEX idx_content ON articles(content); SELECT * FROM articles WHERE MATCH(content) AGAINST('數(shù)據(jù)庫(kù)'); - ?? 不適用于電商商品名等短文本(用 ES 更合適)。
2.空間索引(SPATIAL Index)
- 用于
GEOMETRY類(lèi)型字段(如地圖坐標(biāo)、區(qū)域)。 - 僅 MyISAM 和 InnoDB(MySQL 5.7+)支持。
- 使用
R-TREE結(jié)構(gòu),支持ST_Contains()等空間函數(shù)。
四、不推薦或已廢棄的索引
| 索引類(lèi)型 | 說(shuō)明 |
|---|---|
| HASH 索引 | Memory 引擎支持,InnoDB 不支持(但自適應(yīng)哈希索引 AHI 是內(nèi)部?jī)?yōu)化) |
| RTREE 索引 | 舊版 MyISAM 用,現(xiàn)已被 SPATIAL 取代 |
?? InnoDB 的 自適應(yīng)哈希索引(Adaptive Hash Index, AHI) 是 InnoDB 自動(dòng)為熱點(diǎn)索引頁(yè)構(gòu)建的內(nèi)存哈希結(jié)構(gòu),無(wú)需手動(dòng)創(chuàng)建,可通過(guò)
SHOW ENGINE INNODB STATUS查看。
五、索引設(shè)計(jì)黃金法則(電商場(chǎng)景重點(diǎn))
- 主鍵自增:避免 UUID 導(dǎo)致聚簇索引頻繁頁(yè)分裂。
- 組合索引合理排序:高頻過(guò)濾字段放前,范圍查詢字段放后(如
(user_id, create_time))。 - 避免冗余索引:
(a,b)和(a)同時(shí)存在是冗余的。 - 大字段慎建索引:如
description字段,優(yōu)先考慮前綴索引或異構(gòu)存儲(chǔ)(如 Elasticsearch)。 - 監(jiān)控慢查詢:用
EXPLAIN分析是否命中索引,關(guān)注type(最好ref/range,避免ALL)。
六、查看索引命令
-- 查看表索引 SHOW INDEX FROM table_name; -- 查看執(zhí)行計(jì)劃 EXPLAIN SELECT * FROM orders WHERE user_id = 100; -- 查看索引使用統(tǒng)計(jì)(MySQL 8.0+) SELECT * FROM performance_schema.table_io_waits_summary_by_index_usage WHERE object_schema = 'your_db' AND object_name = 'your_table';
? 總結(jié):
在電商開(kāi)發(fā)中,主鍵索引 + 唯一索引 + 合理的組合索引 足以覆蓋 95% 場(chǎng)景。
牢記:索引不是越多越好,而是越精準(zhǔn)越好。
到此這篇關(guān)于MySQL有5種索引類(lèi)型及其特點(diǎn)的文章就介紹到這了,更多相關(guān)MySQL索引類(lèi)型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql優(yōu)化之路----hash索引優(yōu)化
本文是筆者自己做的關(guān)于mysql的優(yōu)化方面的小測(cè)試,暫時(shí)僅僅做了hash索引優(yōu)化的測(cè)試,以后會(huì)做更多方面,希望能夠給您帶來(lái)收獲,祝您工作愉快。2014-08-08
關(guān)于mysql數(shù)據(jù)庫(kù)誤刪除后的數(shù)據(jù)恢復(fù)操作說(shuō)明
下面小編就為大家?guī)?lái)一篇關(guān)于mysql數(shù)據(jù)庫(kù)誤刪除后的數(shù)據(jù)恢復(fù)操作說(shuō)明。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
Mysql之EXPLAIN顯示using filesort介紹
EXPLAIN 是mysql解釋select查詢的一個(gè)關(guān)鍵字,可以很方便的用于調(diào)試2012-02-02
MySQL中IF語(yǔ)句的基礎(chǔ)及進(jìn)階用法
在Mysql數(shù)據(jù)庫(kù)中實(shí)現(xiàn)判斷功能有很多方式,具體又分為函數(shù)和if語(yǔ)句形式,下面這篇文章主要給大家介紹了關(guān)于MySQL中IF語(yǔ)句的基礎(chǔ)及進(jìn)階用法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
MySQL8.0+版本1045錯(cuò)誤的問(wèn)題及解決辦法
這篇文章主要介紹了MySQL8.0+版本1045錯(cuò)誤解決辦法,使用命令行登錄MySQL報(bào)錯(cuò)1045 Access denied for user ‘root’@‘localhost’ (using password:YES),折騰半天才解決問(wèn)題,需要的朋友可以參考下2022-08-08

