mysql索引

MySQL 索引入门(InnoDB 视角)

1. 为什么要使用索引

使用索引的核心目标是提升查询性能,主要有以下几点:

  1. 减少磁盘 I/O(使用高效数据结构,更快定位目标页)
  2. 减少扫描行数(降低 CPU 过滤成本)
  3. 支持高效排序 / 分组 / 范围查询

2. 索引的代价与注意点

索引有明显收益,但也有代价:

  1. 占用额外存储空间(需要保存额外索引结构)
  2. INSERT / UPDATE / DELETE 变慢(需要维护索引)
  3. 索引过多会增加优化器决策与维护成本

注意:表上有索引,不代表 SQL 一定会用索引。比如小表(几百行)全表扫描可能更优。


3. InnoDB 存储引擎(MySQL 默认)

3.1 使用的数据结构

InnoDB 使用 B+Tree 。其存储单位是页(Page) ,默认页大小通常为 16KB,本质是由页组成的多叉树。

  1. 非叶子节点:存储 键值 + 子页指针,用于导航
  2. 叶子节点:存储真正数据项
    • 聚簇索引叶子页:存整行记录
    • 二级索引叶子页:存索引列 + 主键值
  3. 叶子页之间有双向链表:支持范围查询和顺序扫描

3.2 对比其他数据结构

  • B 树 vs B+ 树 :B+ 树是 B 树的改进版本,针对范围查询、ORDER BYJOIN 等场景更友好。
  • MySQL 常用 B+ 树;MongoDB 常见实现与场景不同,偏文档模型与点查负载,具体取决于引擎实现与业务模式。

3.3 InnoDB 索引模型

  1. 聚簇索引(Clustered Index)

    • 叶子节点存整行数据
    • 表数据本身按该索引组织
    • 可理解为:主键 B+Tree 与数据组织在一起
  2. 二级索引(Secondary Index)

    • 叶子节点存 二级索引列值 + 主键值
    • 不存整行
    • 二级索引查整行时,先拿主键再去聚簇索引取行,这一步叫回表
    • 减少回表通常是优化重点

4. MySQL 常见索引类型

  1. PRIMARY KEY(主键索引)
  2. UNIQUE(唯一索引)
  3. INDEX(普通索引)
  4. 复合索引(联合索引)

5. 常见索引声明样例

sql 复制代码
-- 0) 示例表
CREATE TABLE users (
  id BIGINT PRIMARY KEY AUTO_INCREMENT,
  email VARCHAR(100) NOT NULL,
  phone VARCHAR(20),
  age INT,
  status TINYINT,
  created_at DATETIME,
  first_name VARCHAR(50),
  last_name VARCHAR(50)
);

-- 1) 主键索引(PRIMARY KEY)
-- 方式A:建表时声明(上面 id 已声明)
-- 方式B:后加主键
ALTER TABLE users ADD PRIMARY KEY (id);

-- 2) 唯一索引(UNIQUE)
-- 单列唯一
CREATE UNIQUE INDEX uk_users_email ON users(email);

-- 联合唯一(例如姓名组合唯一)
CREATE UNIQUE INDEX uk_users_name ON users(first_name, last_name);

-- 3) 普通索引(INDEX)
-- 单列普通索引
CREATE INDEX idx_users_age ON users(age);

-- 4) 联合索引 / 复合索引
-- 常见查询:where status=? and created_at>=? order by created_at desc
CREATE INDEX idx_users_status_created ON users(status, created_at);

-- 5) 删除索引
DROP INDEX idx_users_age ON users;

-- 6) 查看索引
SHOW INDEX FROM users;

6. 小结

本文只讲索引,总结为一下段落:

  • 为什么需要索引
  • 索引优缺点
  • InnoDB 的 B+Tree 与存储结构
  • 聚簇索引与二级索引
  • 常见索引类型与建索引 SQL 样例
相关推荐
Turnip120220 小时前
深度解析:为什么简单的数据库"写操作"会在 MySQL 中卡住?
后端·mysql
爱可生开源社区20 小时前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1771 天前
《从零搭建NestJS项目》
数据库·typescript
加号32 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏2 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐2 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再2 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
WeiXin_DZbishe2 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5
tryCbest2 天前
数据库SQL学习
数据库·sql
jnrjian2 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle