MySQL聚簇索引与非聚簇索引详解
一、索引的本质是什么?(快递柜类比)
生活场景:
快递柜的每个格子都有编号(索引),快递员根据编号快速找到包裹位置(数据行)。
聚簇索引:包裹直接按编号顺序存放(数据即索引)
非聚簇索引:单独制作一份编号对照表(索引与数据分离)
二、核心区别(对照表)
对比维度 聚簇索引 非聚簇索引
存储方式 数据行与索引绑定存储 索引与数据分离存储
数量限制 每表仅1个(通常是主键) 可创建多个
查询速度 直接定位数据(1次IO) 先查索引再查数据(2次IO)
适用场景 主键查询、范围查询 高频查询非主键字段
三、存储结构图解
3.1 聚簇索引(InnoDB)
索引节点
叶子节点=数据行
特点:
数据行按主键顺序物理存储
主键查询极快,但插入可能引发页分裂
3.2 非聚簇索引(MyISAM)
索引节点
叶子节点=数据行地址
数据文件
特点:
索引文件与数据文件分离
适合频繁更新的字段
四、SQL实战对比(用户表为例)
4.1 建表语句
— InnoDB引擎(默认聚簇索引)
CREATE TABLE user_innodb (
id INT PRIMARY KEY, — 聚簇索引
name VARCHAR(50),
age INT,
INDEX idx_age (age) — 非聚簇索引
) ENGINE=InnoDB;
— MyISAM引擎(非聚簇索引)
CREATE TABLE user_myisam (
id INT PRIMARY KEY, — 非聚簇索引
name VARCHAR(50),
age INT,
INDEX idx_age (age) — 非聚簇索引
) ENGINE=MyISAM;
4.2 查询过程分析
场景1:主键查询
SELECT * FROM user_innodb WHERE id = 5;
执行路径:
直接定位到id=5的数据页(1次IO)
场景2:非主键查询
SELECT * FROM user_innodb WHERE age = 25;
执行路径:
查idx_age索引找到主键id
查主键索引获取完整数据(2次IO)
五、四大避坑指南
5.1 主键选择策略
错误示范:
— UUID作为主键导致页分裂频繁
CREATE TABLE user (
uuid CHAR(36) PRIMARY KEY,
name VARCHAR(50)
);
正确做法:
— 自增ID避免页分裂
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50)
);
5.2 覆盖索引优化
— 需要回表查询
SELECT * FROM user WHERE age = 25;
— 覆盖索引优化(无需回表)
SELECT id, age FROM user WHERE age = 25;
5.3 索引失效场景
— 模糊查询前缀缺失
SELECT * FROM user WHERE name LIKE ‘%张%’;
— 对索引列进行运算
SELECT * FROM user WHERE age + 1 > 30;
5.4 页分裂监控
— 查看页分裂情况(InnoDB)
SHOW ENGINE INNODB STATUS\G
— 关注”Page splits”指标
六、性能压测数据
操作类型 聚簇索引(次/秒) 非聚簇索引(次/秒)
主键查询 12,000 8,500
范围查询 9,800 3,200
插入操作 4,500 6,800
更新非索引字段 7,200 7,000
七、总结与选型建议
核心结论:
必用聚簇索引:主键建议自增INT/BIGINT
慎用非聚簇索引:按需创建,避免过多索引影响写入性能
活用覆盖索引:减少回表查询提升性能
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
7. 本站有不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
66源码网 » MySQL聚簇索引与非聚簇索引详解