当过滤后的数据量较大时,回表带来的海量随机 I/O成本会呈指数级上升。这也是为什么有时候明明加了索引,查询反而比全表扫描还要慢的原因
随机IO
因为它会产生随机磁盘IO
非聚簇索引的叶子节点只存储索引列的值和对应的主键ID,当需要回表时,数据库必须拿着主键ID去聚簇索引查找完整数据。
虽然二级索引中匹配的记录,可能是挨在一起的,但是他们对应的主键ID在物理磁盘上往往是不连续的。
每次拿着主键去主键树查数据,都可能触发一次独立的磁盘寻道,在机械硬盘下,单次随机IO耗时可能高达10ms以上,固态硬盘下,延迟也会显著增加。如果查询返回1万条数据,就可能触发1万次随机IO,比直接顺序全表扫描还慢。
内存缓冲池命中率下降
回表操作需要同时加载二级索引页和聚簇索引页到内存中,由于回表的数据在物理页上不连续,会大量占用缓冲池的空间,导致其他高频查询的缓存命中率大幅下降,进而引发整体数据库性能的退化。
排序和临时表
回表查出的完整数据需要参与排序操作时,数据库将无法利用索引本身的有序性 ,会强制触发 内存或磁盘级别的二次排序(using fileSort ),进一步消耗CPU和IO
高并发性能雪崩
高并发场景下,大量请求触发回表,会导致磁盘IO队列深度激增,数据库连接池被慢查询占满,请求排队超时,最终引发整个服务不可用