MySQL 中的索引是提高查詢性能的重要工具,它通過構建數據結構來加速數據檢索。MySQL 支持多種索引類型,每種類型適用于不同的場景。以下是 MySQL 中主要的索引類型及其特點:
1. B-Tree 索引(默認類型)
- 結構:基于平衡多路搜索樹(B-Tree),適用于等值查詢(
=
)、范圍查詢(>
、<
、BETWEEN
)、排序(ORDER BY
)和分組(GROUP BY
)。 - 特點:
- 葉子節點存儲數據或主鍵值(InnoDB 的聚簇索引直接存儲數據,非聚簇索引存儲主鍵值)。
- 支持前綴匹配(如
LIKE 'abc%'
),但LIKE '%abc'
無法利用索引。 - 適用于多列組合索引(遵循最左前綴原則)。
- 適用場景:全值匹配、范圍查詢、排序、分組。
- 示例:
CREATE INDEX idx_name ON users(name); -- 單列索引 CREATE INDEX idx_name_age ON users(name, age); -- 組合索引
2. Hash 索引
- 結構:基于哈希表,僅支持等值查詢(
=
、IN
),不支持范圍查詢或排序。 - 特點:
- 查詢效率高(O(1) 時間復雜度),但僅適用于內存表(如
MEMORY
引擎)或特定場景(如InnoDB
的自適應哈希索引)。 - 無法避免全表掃描(哈希沖突時需遍歷鏈表)。
- 查詢效率高(O(1) 時間復雜度),但僅適用于內存表(如
- 適用場景:等值查詢(如緩存場景)。
- 示例:
CREATE TABLE hash_table (id INT,name VARCHAR(100),INDEX USING HASH (name) -- MEMORY 引擎支持 ) ENGINE=MEMORY;
3. Full-Text 索引(全文索引)
- 結構:專為文本搜索設計,支持對
CHAR
、VARCHAR
、TEXT
列進行全文檢索。 - 特點:
- 使用倒排索引技術,支持自然語言搜索(
MATCH ... AGAINST
)、布爾模式搜索等。 - 僅適用于
MyISAM
和InnoDB
(MySQL 5.6+)。
- 使用倒排索引技術,支持自然語言搜索(
- 適用場景:文本內容搜索(如博客文章、商品描述)。
- 示例:
CREATE FULLTEXT INDEX idx_content ON articles(content); SELECT * FROM articles WHERE MATCH(content) AGAINST('MySQL 索引');
4. R-Tree 索引(空間索引)
- 結構:基于多維空間數據(如地理坐標),支持空間數據查詢(如
MBRContains
、ST_Distance
)。 - 特點:
- 僅適用于
MyISAM
和InnoDB
(MySQL 5.7+)。 - 用于地理信息系統(GIS)或空間數據分析。
- 僅適用于
- 適用場景:地理位置查詢(如附近商家、區域范圍搜索)。
- 示例:
CREATE SPATIAL INDEX idx_location ON stores(location); -- location 為 GEOMETRY 類型 SELECT * FROM stores WHERE MBRContains(GeomFromText('POLYGON(...)'), location);
5. 前綴索引(Partial Index)
- 結構:對字符串列的前 N 個字符創建索引,節省存儲空間。
- 特點:
- 適用于長字符串(如 URL、郵箱),但可能降低選擇性(重復值增多)。
- 需合理選擇前綴長度(通過
COUNT(DISTINCT LEFT(col, N))
評估)。
- 適用場景:長字符串列的等值查詢。
- 示例:
CREATE INDEX idx_email_prefix ON users(email(10)); -- 對 email 前 10 個字符建索引
6. 唯一索引(Unique Index)
- 結構:強制列值唯一(允許
NULL
,但NULL
值不重復)。 - 特點:
- 保證數據唯一性,同時可作為普通索引加速查詢。
- 適用于主鍵(
PRIMARY KEY
)或唯一約束(UNIQUE KEY
)。
- 適用場景:需要唯一性的字段(如用戶名、身份證號)。
- 示例:
CREATE UNIQUE INDEX idx_username ON users(username); -- 或直接定義唯一約束 ALTER TABLE users ADD CONSTRAINT uk_email UNIQUE (email);
7. 主鍵索引(Primary Key Index)
- 結構:特殊的唯一索引,不允許
NULL
值,且每張表只能有一個。 - 特點:
- 在 InnoDB 中,主鍵索引是聚簇索引(數據按主鍵順序存儲)。
- 用于標識行數據,是表的核心索引。
- 適用場景:表的唯一標識符(如自增 ID、UUID)。
- 示例:
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,name VARCHAR(100) );
8. 復合索引(Multi-Column Index)
- 結構:在多列上創建的索引,遵循最左前綴原則。
- 特點:
- 查詢需從索引的最左列開始匹配(如
(a,b,c)
索引可加速a
、a,b
、a,b,c
的查詢)。 - 避免“索引失效”問題(如跳過最左列或使用范圍查詢后無法利用后續列)。
- 查詢需從索引的最左列開始匹配(如
- 適用場景:多列聯合查詢(如姓名+年齡篩選)。
- 示例:
CREATE INDEX idx_name_age ON users(name, age); -- 有效查詢: SELECT * FROM users WHERE name = 'Alice' AND age = 25; -- 無效查詢(跳過最左列): SELECT * FROM users WHERE age = 25;
9. 自適應哈希索引(Adaptive Hash Index, AHI)
- 結構:InnoDB 自動為頻繁訪問的索引頁構建哈希索引,無需手動創建。
- 特點:
- 僅在內存中維護,適用于等值查詢(如
=
、IN
)。 - 無法手動控制,由 InnoDB 引擎自動管理。
- 僅在內存中維護,適用于等值查詢(如
- 適用場景:高并發等值查詢的熱點數據。
10. 函數索引(虛擬列索引)
- 結構:對計算列(如
LOWER(name)
)創建索引,避免在查詢中重復計算。 - 特點:
- 需 MySQL 5.7+ 或 MariaDB 支持。
- 適用于表達式查詢(如不區分大小寫的搜索)。
- 示例:
ALTER TABLE users ADD COLUMN name_lower VARCHAR(100) AS (LOWER(name)) STORED; CREATE INDEX idx_name_lower ON users(name_lower); SELECT * FROM users WHERE name_lower = 'alice';
索引選擇建議
- 優先選擇 B-Tree 索引:適用于大多數場景(等值、范圍、排序)。
- 避免過度索引:每個索引會增加寫入開銷(
INSERT
/UPDATE
/DELETE
)。 - 利用最左前綴原則:設計復合索引時,將高選擇性列放在左側。
- 監控索引使用情況:通過
EXPLAIN
分析查詢計劃,刪除未使用的索引。
總結
索引類型 | 適用場景 | 引擎支持 | 示例 |
---|---|---|---|
B-Tree | 全值、范圍、排序、分組 | MyISAM、InnoDB | CREATE INDEX idx ON t(col); |
Hash | 等值查詢(內存表) | MEMORY、InnoDB(AHI) | INDEX USING HASH (col) |
Full-Text | 文本搜索 | MyISAM、InnoDB | CREATE FULLTEXT INDEX ... |
R-Tree | 空間數據查詢 | MyISAM、InnoDB | CREATE SPATIAL INDEX ... |
前綴索引 | 長字符串列的等值查詢 | MyISAM、InnoDB | INDEX (col(10)) |
唯一索引 | 唯一性約束 | 所有引擎 | CREATE UNIQUE INDEX ... |
主鍵索引 | 表的唯一標識符 | 所有引擎 | PRIMARY KEY (col) |
復合索引 | 多列聯合查詢 | MyISAM、InnoDB | INDEX (a, b, c) |
根據實際查詢需求選擇合適的索引類型,并通過 EXPLAIN
驗證優化效果。
我正在程序員刷題神器面試鴨上高效準備面試,9000+ 高頻面試真題、800 萬字優質題解,覆蓋主流編程方向,跟我一起刷原題、過面試:點擊進入