当前位置: 首页 > news >正文

从零起步学习MySQL || 第八章:索引深入理解及高级运用(结合常见优化问题讲解)

一、为什么要创建索引(Index)?

索引的作用:
索引就像一本书的“目录”,让数据库在查询数据时可以“快速定位”记录,而不是全表扫描。

优点:

  • 大大提高数据检索速度

  • 加快表之间的连接(join)

  • 在分组(GROUP BY)、排序(ORDER BY)时也能提高效率

缺点:

  • 索引需要占用额外的磁盘空间

  • 插入、删除、更新数据时,索引也要维护,可能会变慢


二、什么时候需要创建索引

可以简单理解为一句话:

“凡是经常出现在 WHEREJOINORDER BYGROUP BY 的列,都值得考虑建立索引。”

 具体场景:

  1. 主键和唯一键

    • 主键会自动创建唯一索引。

    • 唯一键(UNIQUE)可以保证数据唯一性。

  2. 经常用作查询条件的字段

    SELECT * FROM user WHERE email = 'test@xupt.edu.cn';
    

     应给 email 创建索引。

  3. 用于排序的字段

    SELECT * FROM article ORDER BY create_time DESC;
    

     给 create_time 建索引可避免文件排序。

  4. 用于分组统计的字段

    SELECT department, COUNT(*) FROM employee GROUP BY department;
    

     department 列可建索引。

  5. 多表连接时用作连接条件的字段

    SELECT * FROM student s JOIN score c ON s.id = c.student_id;
    

     student.idscore.student_id 都应建索引。


三、什么时候不需要创建索引

索引不是越多越好,错误的索引会拖慢性能。

 不建议建索引的情况:

  1. 数据量很小的表

    • 比如只有几百行,MySQL 直接全表扫描更快。

  2. 频繁更新的字段

    • 每次更新都要维护索引,会拖慢性能。

  3. 高重复度的字段

    • 如“性别”、“是否删除(0/1)”,区分度太低。

    • 索引选择性低,优化效果几乎没有。

  4. 查询中很少用到的字段

    • 从不出现在 WHEREORDER BYGROUP BY 中的列没必要建索引。


四、索引优化方法

接下来讲几个常见的索引优化技巧,在面试中也经常被问到


1️⃣ 前缀索引优化(Prefix Index)

当字符串字段太长(如邮箱、URL、UUID)时,索引整个字段会浪费空间。
可以只取前几个字符建立索引。

ALTER TABLE user ADD INDEX idx_email (email(10));

 优点:

  • 占用空间小,比较速度快。

 缺点:

  • 可能降低“区分度”,MySQL 仍可能要回表验证。

 实战建议:
SELECT COUNT(DISTINCT LEFT(email, N)) / COUNT(*) 来测试前缀长度的区分度。


2️⃣ 覆盖索引优化(Covering Index)

“覆盖索引”指的是查询的字段都在索引中,不用回表读取数据。

-- 索引包含 (id, name)
SELECT id, name FROM student WHERE id = 1;

 优点:

  • 避免回表(减少IO),查询更快。

 优化手段:
只查需要的字段;用 EXPLAIN 查看 Extra 字段中是否有 Using index


3️⃣ 主键索引自增优化(Auto Increment Primary Key)

InnoDB 的主键索引是聚簇索引(Clustered Index),数据按照主键顺序存储。
如果主键是随机的(比如 UUID),容易导致数据页分裂、碎片多、写入慢。

 建议:

id BIGINT AUTO_INCREMENT PRIMARY KEY

 自增主键能保证数据顺序插入,性能最优。


4️⃣ 索引列设置为 NOT NULL

MySQL 在处理 NULL 时无法高效使用索引(特别是范围查询、排序时)。

 建议:

  • 避免在索引列中使用 NULL

  • 可以设置默认值,比如 DEFAULT ''DEFAULT 0


5️⃣ 防止索引失效的情况

索引建立了 ≠ 一定会被用到。
常见的“索引失效”场景如下

场景例子原因
使用 ORWHERE a=1 OR b=2可能导致全表扫描
函数操作WHERE YEAR(create_time)=2025函数操作让索引失效
模糊匹配 % 开头LIKE '%abc'无法利用前缀索引
隐式类型转换WHERE num = '123'类型不同会触发转换
复合索引未遵守“最左前缀原则”索引(a,b,c),只用 b 查询无法使用索引

 解决方法:

  • 保持字段类型一致

  • 避免对索引列进行计算或函数操作

  • 对字符串匹配尽量使用前缀匹配 LIKE 'abc%'

  • 使用复合索引时遵守“最左前缀原则”


五、总结速记表

类型原则/技巧说明
创建索引WHERE / JOIN / ORDER / GROUP字段提高查询效率
不建索引小表 / 高频更新 / 低区分度字段节省资源
前缀索引email(10)节省空间,需测试区分度
覆盖索引查询字段全在索引中避免回表
主键自增AUTO_INCREMENT防止页分裂
NOT NULL索引列不应为NULL提高效率
索引失效函数、OR、%abc、类型不匹配避免这些写法

http://www.dtcms.com/a/520916.html

相关文章:

  • ASP.NET酒店管理系统源码
  • 汕头企业网站公司高端大气上档次网站
  • 昆明企业建网站多少钱河源网站设计怎么做
  • JavaEE知识点梳理与整合
  • 充值网站制作购物网站制作公司
  • 在线免费网站模板机械外贸有哪些平台
  • 基于MATLAB的Relief-F算法实现
  • 滥用 CDN 缓存功能(传播恶意内容)
  • 正点原子RK3568学习日志18-一个驱动兼容不同设备
  • SpringBoot-Web开发之静态资源管理
  • 广州做网站代理商建立网站的目录结构应注意哪些问题
  • 初识C语言12. 结构体(自定义类型的核心工具)
  • webrtc源码走读(二)-QOS-RTT
  • 【Java】线程安全问题
  • 数据结构算法学习:LeetCode热题100-链表篇(下)(随机链表的复制、排序链表、合并 K 个升序链表、LRU 缓存)
  • 网络营销网站 功能南京微信小程序开发制作
  • 域名打不开原来的网站手机免费网站制作
  • 中药饮片网购是什么?主要的市场特点及未来发展潜力如何?
  • 自己做的网站数据库360优化大师app
  • Python-__init__函数
  • 沈阳网站维护公司网站建设财务怎么入账
  • JavaEE:知识总结(一)
  • 各家高性能MCU的内置Flash逐渐走向MRAM之路,关于嵌入式 MRAM 的性能和能效
  • Leetcode 35
  • GPIO口输出
  • 专教做美食的网站胶州哪里有做网站的
  • 企业网站制作 徐州网站设计原则的历史
  • 隐私保护与数据安全合规(十三)
  • 2025年高真空共晶炉排名
  • 网站做转链接违反版权吗wordpress页面不显示子类