阿亮随手记:MySQL移除查询缓存、子查询优化深分页、自增主键溢出、索引失效

依旧是记录一些小知识点

为什么MySQL要移除我们的查询缓存?

查询缓存的原理:

把一条完全一样的 SQL 的结果集缓存到服务层,下次直接命中就返回,不用再执行。

但它有巨大缺陷 ,所以 8.0 直接删掉了:

  1. 缓存失效太频繁,命中率极低

只要表有任何写入(insert/update/delete),这个表的所有查询缓存全部失效。

互联网业务写多读多,缓存刚建就失效,基本白忙活。

  1. 维护开销巨大 ,反而拖慢性能

要维护缓存的哈希表、锁、清理、淘汰。

高并发下,查询缓存的互斥锁(mutex)会成为瓶颈,甚至越开越慢。

  1. 使用限制非常多

语句必须完全一模一样,空格、大小写不一样都不算命中。

包含 now() 、 rand() 、 current_user() 等不确定函数,不缓存。

视图、存储过程、触发器也会影响缓存。

4.现代缓存方案更好

业务层用 Redis、Memcached 更灵活、可控、可扩展。

InnoDB 本身有缓冲池(Buffer Pool),缓存数据和索引,比查询缓存高效得多。

子查询优化深分页

深分页 + 子查询优化(最终版·面试直接说)

深分页为什么慢?

因为原来的写法,是先把符合 WHERE 条件的数据全部回表、查全字段,再排序,再丢掉前面大量数据。

要回表几十万、几百万次

读了大量无用的整行数据

内存、IO 开销巨大

用子查询 + 索引覆盖优化后:

  1. 子查询只查主键 ID

利用联合索引(WHERE 字段 + ORDER BY 字段),在索引里就完成过滤、排序、分页,

全程不回表,只拿到最后需要的那 10 个 ID。

虽然也要跳过前面大量数据,但只走索引、不回表,开销极小。

  1. 外层只通过这 10 个 ID 回表 10 次

只查真正要返回的那几行,回表次数从几百万 → 10 次。

自增主键溢出

MySQL 自增组件(AUTO_INCREMENT)用完上限,分显式自增主键和**隐式自增(InnoDB 隐藏主键)**两种情况,结果完全不同:

  1. 显式自增主键(用户自定义)
  • 类型: INT / BIGINT 等,设置了 AUTO_INCREMENT 。

  • 上限:达到类型最大值(如 BIGINT UNSIGNED 是 18446744073709551615 )。

  • 结果:直接报错 1062 (主键冲突)。

  • 原因:自增组件会继续生成当前最大值+1,但该值超出类型范围或已存在,插入失败,不会自动重置。

  1. 隐式自增(InnoDB 隐藏主键)
  • 场景:表没有显式主键时,InnoDB 会自动生成一个6字节的隐藏自增主键(row_id)。

  • 上限:6字节无符号整数,最大值为 2^48 - 1 。

  • 结果:达到上限后,会从 0 开始循环复用。

  • 后果:严重数据覆盖!因为新行的隐藏主键会覆盖掉之前行的主键,导致旧数据被"隐形删除",查询和数据完整性彻底错乱。

索引失效是什么导致的

第一种,是优化器觉得索引效率不高,主动选择不走索引。

比如:

  • 表的数据量比较小,优化器认为全表扫描更快;

  • 索引区分度很低,比如性别、状态之类,优化器就不走索引;

  • 查询返回的数据量太大,优化器判断走索引成本更高,直接全表扫描。

第二种,是我们写的 SQL 本身导致索引失效。

比如:

  • 在索引字段上做计算 ,像 age + 1 = ? ,索引直接失效;

  • 在索引字段上使用函数 ,比如 year(create_time) = 2026 ,索引失效;

  • like 查询以 % 开头,比如 like '%abc' ,索引失效;

  • 隐式类型转换 ,字符串字段用数字去查,索引失效;

  • 使用or 连接条件,有一侧没有索引,整个索引失效;

  • 联合索引违反最左前缀原则 ,也会导致索引失效;

不过现在 MySQL 支持跳跃索引,某些场景下即使跳过前面字段,也可能还会走索引;

  • 使用 !=、<>、is not null、not in 这类条件 ,也容易导致索引失效;

  • 还有 order by,如果数据量小,MySQL 可能直接用 sort buffer 排序, 而不走索引排序。

相关推荐
2301_781571428 小时前
Golang格式化输出占位符都有什么_Golang fmt占位符教程【通俗】
jvm·数据库·python
养肥胖虎8 小时前
RAG学习笔记(3):区分数据库检索与RAG的使用场景
数据库·ai·rag
_ku_ku_9 小时前
数据库系统原理 · 数据库应用开发 · 自学总结
数据库
长谷深风1119 小时前
索引提速秘籍【个人八股】
mysql·b+树·索引·索引设计原则·存储引擎优化·索引维护成本·字段选择策略
No8g攻城狮9 小时前
【人大金仓】wsl2+ubuntu22.04安装人大金仓数据库V9
java·数据库·spring boot·非关系型数据库
山峰哥10 小时前
SQL慢查询调优实战:从全表扫描到索引覆盖的完整复盘
前端·数据库·sql·性能优化
Irene199110 小时前
在 WSL 中下载安装 MySQL,连接到 SQLyog(MySQL 安装在 WSL vs Windows 本地对比)
mysql·wsl
代码中介商10 小时前
Redis入门:5大数据类型全解析
数据库·redis·缓存
渣渣盟10 小时前
数据库设计范式详解(纯小白版)
数据库·oracle·软考·数据库工程师
夜雪闻竹12 小时前
Cursor 对话导入:解析 SQLite 里的宝藏
数据库·sqlite·ai编程