没索引时WHERE条件触发全表扫描,需逐页随机IO读取;索引失效场景包括隐式类型转换、函数操作、跳过联合索引最左前缀及低选择性列,导致B+树退化为线性扫描。

没索引时,WHERE条件直接触发全表扫描
只要查询的 WHERE 条件列没索引,InnoDB 就必须从第一个数据页开始,一页一页读到磁盘末尾——这不是“找数据”,是“翻整本电话簿”。每页读取都是一次独立的随机IO,因为数据页在磁盘上物理位置不连续。哪怕只查1行,也可能触发成百上千次磁盘寻道。
索引失效让B+树退化成线性扫描
即使建了索引,以下情况也会让索引形同虚设:
-
WHERE name = 'Alice',但name列是VARCHAR,而传参用了CHAR——隐式类型转换导致索引失效 -
WHERE UPPER(name) = 'ALICE'——函数包裹索引列,优化器无法走索引 - 联合索引
(a, b, c),但查询只用WHERE b = 1——跳过最左前缀,索引被跳过 - 索引列上大量重复值(比如
status只有 0/1),选择性太低,优化器主动放弃使用
高并发下随机IO会迅速压垮机械盘和缓冲池
单次随机IO延迟在机械硬盘上常达 8–15ms;SSD 好些,但也比顺序IO慢一个数量级。更致命的是:innodb_buffer_pool_size 再大也缓存不了散落在磁盘各处的数据页。当并发查询增多,缓冲池命中率暴跌,大量请求被迫回磁盘——这时不是“几个慢查询”,而是整个实例的 io_wait 指标持续飙红,Threads_running 堆积,连接数打满。
重建索引不等于解决根本问题
OPTIMIZE TABLE 或 ALTER TABLE ENGINE=InnoDB 能整理碎片、让数据页物理连续,但只对已有数据有效。如果业务写入模式本身就不利于顺序落盘(比如按时间倒序插入、主键非自增),新数据仍会快速产生新的随机IO热点。真正要盯住的是:查询是否真的能走索引、索引是否覆盖高频路径、写入主键是否具备聚集性。



















