MySQL 索引的相关知识

一、索引的作用

1. 核心作用

  • 加速查询:这是索引最主要的作用。没有索引时,MySQL 需要全表扫描(逐行检查),数据量大时非常慢;有索引时,可以直接定位到数据

  • 加速排序 :ORDER BY 可以利用索引避免额外的排序操作

  • 加速分组 :GROUP BY 可以利用索引提高效率

  • 加速去重 :DISTINCT 可以利用索引

  • 维护唯一性:唯一索引可以保证数据的唯一性约束

2. 代价(副作用)

  • 占用额外存储空间:索引本身也是数据结构,需要磁盘空间

  • 降低写操作速度 :每次 INSERT、UPDATE、DELETE 时,都需要同时维护索引结构

  • 增加内存消耗:查询时索引需要加载到内存

二、索引的数据结构

MySQL 主要使用 B+树 作为索引结构:

复制代码
B+树特点:
- 所有数据都存储在叶子节点
- 叶子节点之间通过指针相连(方便范围查询)
- 非叶子节点只存储键值,不存储数据
- 树的高度很低(通常3-4层),查询效率高

三、索引类型

php 复制代码
| 类型                      | 说明              | 使用场景                        |
| ----------------------- | --------------- | --------------------------- |
| **主键索引 (Primary Key)**  | 唯一且非空,每张表只能有一个  | 表的主标识                       |
| **唯一索引 (Unique)**       | 值必须唯一,允许一个 NULL | 需要唯一约束的字段(如邮箱、手机号)          |
| **普通索引 (Normal/Index)** | 无唯一约束           | 频繁查询的字段                     |
| **全文索引 (Fulltext)**     | 针对文本内容          | 大文本搜索(MySQL 5.6+ InnoDB 支持) |
| **组合索引 (Composite)**    | 多个字段联合索引        | 多条件查询                       |

四、索引设计原则与技巧

原则 1:为 WHERE 条件中的字段建索引

sql 复制代码
-- 频繁这样查询
SELECT * FROM users WHERE age = 25;

-- 应该给 age 建索引
CREATE INDEX idx_age ON users(age);

原则 4:选择性高的字段更适合建索引

选择性 = 不重复值数量 / 总记录数

  • 选择性越接近 1,索引效果越好

  • 选择性很低的字段(如性别,只有男女两种值)不适合单独建索引

sql 复制代码
-- 不好:选择性太低
CREATE INDEX idx_gender ON users(gender);  -- 只有男/女,索引效果差

-- 好:选择性高
CREATE INDEX idx_email ON users(email);    -- 几乎不重复

五、索引设计标准/规范建议

sql 复制代码
| 索引类型 | 命名格式          | 示例                   |
| ---- | ------------- | -------------------- |
| 主键   | `pk_表名`       | `pk_users`           |
| 唯一索引 | `uk_字段名`      | `uk_email`           |
| 普通索引 | `idx_字段名`     | `idx_create_time`    |
| 组合索引 | `idx_字段1_字段2` | `idx_user_id_status` |

设计检查清单

在设计索引时,问自己以下几个问题:

  • 这个字段查询频率高吗? 低频查询不值得建索引

  • 这个字段的选择性高吗? 低于 10% 的字段慎重考虑

  • 这个字段会频繁更新吗? 频繁更新的字段建索引会增加维护成本

  • 是否已经有类似的索引? 避免冗余

  • 是否需要覆盖索引优化? 考虑查询的字段组合

  • 索引数量是否过多? 单表不超过 5-7 个

总结

sql 复制代码
| 场景                     | 建议           |
| ---------------------- | ------------ |
| 主键                     | 必须建,用自增整数    |
| 外键                     | 建议建索引        |
| WHERE 条件字段             | 高频查询的建       |
| ORDER BY / GROUP BY 字段 | 考虑建索引        |
| 选择性低的字段                | 不单独建,可放组合索引中 |
| 频繁更新的字段                | 慎重建索引        |
| 小表(<<1000行)            | 不需要索引,全表扫描更快 |
相关推荐
一技安身几秒前
MySQL 8.4.13 LTS 通用二进制包(Linux免安装版)完整教程
linux·mysql·adb
代码派9 分钟前
业务不停机迁移 MySQL 到 TiDB,NineData 数据增量同步实操演示
数据库·mysql·tidb·ninedata·无停机迁移·增量迁移·全量迁移
Gauss松鼠会13 分钟前
GaussDB 中 gsql 与 DBeaver(JDBC)客户端工具查询时间不一致:原因、排查与处理
运维·服务器·数据库·sql·gaussdb·经验总结
Elastic 中国社区官方博客19 分钟前
基于 Jina OCR v1 与 Elasticsearch 的 PDF 智能混合检索与 RAG 系统实战指南
大数据·数据库·elasticsearch·搜索引擎·ocr·jina
我不会起名字32225 分钟前
MySQL 8.0 迁移后 SQL 变慢:执行计划里 3 类被忽略的成本差异
mysql·explain·执行计划·索引下推·成本模型
楚识科技26 分钟前
信创环境下 OCR 部署实践:从麒麟系统到达梦数据库的全栈适配
数据库·ocr
飞浪纪元[FWC–FE]31 分钟前
Qt 构建排错实录:从 MSB 1009 到生成器选型
开发语言·数据库·qt
Paper数据分析-经管学术31 分钟前
1985-2026年中国低空经济专利明细数据库
数据库
RuoyiOffice31 分钟前
SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
java·数据库·spring boot·opengauss·信创
画中有画43 分钟前
时序数据库在物联网系统中的应用
数据库·物联网·时序数据库