知其然,知其所以然
MySQL / InnoDB 2026-09-25

选择性与索引扫描:优化器如何决定走不走索引

本机真实建一张20万行、95%对5%严重倾斜的表,真实对比强制走索引和强制全表扫描的耗时,意外发现MySQL优化器的默认选择对低选择性列反而选错了。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

可重复读:同一个事务为什么两次读到一样的结果

本机真实开两个MySQL连接,一个事务里连续两次COUNT(*),中途另一个连接真实插入并提交了新数据,验证REPEATABLE READ下同一个事务真实两次读到的是不是同一个结果。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

READ COMMITTED:提交之后当前事务能否看见

本机真实把隔离级别切到READ COMMITTED,跑跟上一篇完全一样的两连接实验,看同一个事务里连续两次读到的结果是不是还一样。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

FOR UPDATE:锁定读和普通一致性读的区别

本机真实用一个连接FOR UPDATE锁住一行,另外两个连接分别用普通SELECT和UPDATE去碰这一行,真实测出普通读0.0001秒不受影响、UPDATE被真实阻塞了1.5秒。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

InnoDB 死锁:两个事务互相等会发生什么

本机真实制造一个经典死锁:A锁行1想要行2,B锁行2想要行1,用SHOW ENGINE INNODB STATUS真实拿到InnoDB自己记录的死锁检测报告,看它真实选谁做牺牲品。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

自增主键:回滚之后为什么不会复用编号

本机真实插入3行后开事务插入5行再ROLLBACK,看AUTO_INCREMENT计数器真实是不是也跟着回滚了——真实验证之后发现,下一条真实插入直接跳到了id=9,中间的编号永久消失。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

生成列与函数索引:把计算结果交给索引

本机真实建一张10万行的JSON表,在生成列city上建索引,对比直接查JSON路径表达式和查生成列的真实EXPLAIN与耗时,意外发现优化器能自动识别表达式等价但执行代价仍然不同。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

JSON 字段索引:先生成列还是直接扫描 JSON

本机真实用CREATE INDEX ... ((表达式))直接在JSON路径表达式上建功能索引,真实验证SHOW COLUMNS里不会多出任何可见列——跟上一篇用具名STORED生成列建索引相比,这是另一条不留痕迹的真实路径。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

分区裁剪:日期条件到底读了几个分区

本机真实建一张按年份RANGE分区、30万行的表,用EXPLAIN真实验证日期范围查询的行数估算精确落在单个分区的行数上,再真实测出一个反直觉的结果:这次分区裁剪的查询反而比无条件COUNT(*)慢了约3倍。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

ALGORITHM=INSTANT:加列为什么可以不重建整张表

本机真实在一张200万行的表上,真实测ALGORITHM=INSTANT加一列只要0.0066秒,而改一列的数据类型真实需要ALGORITHM=COPY整表重建,耗时3.0938秒——差了469倍,200万行数据真实完整无损。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

外键级联删除:父行删除后子行去了哪里

本机真实建三张子表,分别用ON DELETE CASCADE、SET NULL、默认RESTRICT,对同一个父行删除操作,真实验证三种真实不同的结局:子行真实被删除、子行的外键列真实变NULL、删除操作真实被拒绝。

MySQL 真实验证 动画演示
MySQL / InnoDB 2026-09-25

唯一索引与 NULL:为什么两个 NULL 可以同时存在

本机真实往一个UNIQUE列里连续插入3个NULL,全部真实成功;紧接着插入两个真实相同的非NULL值,第二次真实立刻报错——同一个唯一索引,对NULL和非NULL值真实是两套判断标准。

MySQL 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号