一、索引概述
索引本质是帮助MySQL高效获取数据的排序数据结构(类似书籍目录),通过减少磁盘I/O次数提升查询效率。其核心价值体现在大数据量场景下的快速定位能力,但同时带来存储和维护成本。
核心特点:
- 优点: 
- 减少数据检索量(时间复杂度从O(n)降至O(log n))
 - 加速排序和分组操作(ORDER BY/GROUP BY)
 - 保证数据唯一性(唯一索引)
 
 - 缺点: 
- 占用额外磁盘空间(索引文件独立存储)
 - 降低写操作性能(INSERT/UPDATE/DELETE需维护索引树)
 - 不恰当的索引设计可能引发性能劣化
 
 
二、索引结构
1. B+Tree(主流结构)
- 层级结构:非叶子节点仅存索引键(Key),叶子节点存储数据指针且形成双向链表 。
 - 优势: 
- 树高可控(一般3-4层支撑千万级数据)
 - 范围查询高效(叶子节点链表直接遍历)
 - 适合磁盘存储(节点大小=磁盘页大小,减少I/O)
 
 
2. Hash索引
- 基于哈希表实现,O(1)时间复杂度的等值查询 。
 - 局限性: 
- 不支持范围查询和排序
 - 哈希冲突影响性能(链表或红黑树处理)
 - 仅Memory引擎原生支持,InnoDB提供自适应哈希(AHI)
 
 
3. 全文索引(Full-Text)
- 基于倒排索引实现,针对TEXT类型字段进行关键词搜索 。
 - 支持自然语言查询(MATCH...AGAINST语法)
 - 仅InnoDB/MyISAM引擎支持
 
三、索引分类
按数据结构划分
| 类型 | 特点 | 适用场景 | 
|---|---|---|
| B+Tree | 支持范围查询、排序,磁盘友好 | 90%以上的索引场景 | 
| Hash | 等值查询极快,不支持范围操作 | 内存表、精确匹配场景 | 
| Fulltext | 文本关键词搜索 | 文章内容检索 | 
按物理存储划分
| 类型 | 特点 | 示例 | 
|---|---|---|
| 聚集索引 | 数据行存储在叶子节点(InnoDB主键索引) | PRIMARY KEY | 
| 非聚集索引 | 叶子节点存储主键值或数据地址,需二次查找 | 普通单列/组合索引 | 
按字段特性划分
| 类型 | 特点 | 语法示例 | 
|---|---|---|
| 主键索引 | 唯一且非空,InnoDB的表数据按主键顺序存储 | PRIMARY KEY (id) | 
| 唯一索引 | 列值唯一,允许NULL | UNIQUE INDEX (email) | 
| 普通索引 | 无唯一性约束,加速查询 | INDEX (name) | 
| 全文索引 | 文本内容分词检索 | FULLTEXT (content) | 
按字段数量划分
| 类型 | 特点 | 优化规则 | 
|---|---|---|
| 单列索引 | 单字段索引 | INDEX (age) | 
| 联合索引 | 多字段组合索引,遵循最左前缀原则 | INDEX (name,age) | 
特殊类型:
- 覆盖索引:索引包含查询所需全部字段,避免回表 
(如SELECT id,name FROM users WHERE name='A',若索引是(name,id)) - 前缀索引:对长字符串前N字符创建索引,节省空间 
(如INDEX (title(10))) 
四、索引语法
1. 通用操作
-- 创建索引 
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name ON table_name (col1 [ASC|DESC], ...); 
-- 修改表添加索引 
ALTER TABLE table_name ADD [UNIQUE|FULLTEXT] INDEX index_name (col1, ...); 
-- 删除索引 
DROP INDEX index_name ON table_name; 
2. 分类示例
主键索引:
-- 建表时指定 
CREATE TABLE users (
id INT AUTO_INCREMENT, 
name VARCHAR(50), 
PRIMARY KEY (id) -- 聚集索引 ); 
-- 修改添加 
ALTER TABLE orders ADD PRIMARY KEY (
order_id); 
联合索引:
-- 优化多条件查询 
CREATE INDEX idx_name_age ON employees (
last_name, hire_date); 
全文索引:
-- 支持文本搜索 
CREATE FULLTEXT INDEX ft_content ON articles (content); 
SELECT * FROM articles WHERE MATCH(content) AGAINST('数据库'); 
前缀索引:
-- 长字段优化 
CREATE INDEX idx_city_prefix ON customers (city(10)); 
五、设计原则
- 高频查询字段优先(WHERE/JOIN/ORDER BY)
 - 区分度高字段前置(如性别字段不宜单独建索引)
 - 避免过度索引(超过5个索引需谨慎评估)
 - 联合索引左前缀匹配(
INDEX(a,b,c)适用a=1 AND b>2,不适用b>2) - 长文本使用前缀/全文索引