已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
背景:订单表 t_order 约 4200 万行,InnoDB,MySQL 8.0.32,已建联合索引 idx_ab (a, b),其中 a 是商户ID(高基数,单值查询命中 200~3000 行不等),b 是创建时间(datetime)。
现象:一条高频查询 SELECT id, a, b FROM t_order WHERE a IN (1001,1002,1003,1004,1005) ORDER BY b DESC LIMIT 20,EXPLAIN 显示 type=range、key=idx_ab、Extra=Using filesort;当 IN 列表里 5 个商户合计命中约 8000 行时,单次 120~300ms,P99 抖动明显。
已尝试与结果:
卡点:我不确定 8.0 在这种「高基数 a 的 IN 多值 + ORDER BY b + LIMIT」组合下,优化器到底有没有可能走索引序而避免 filesort?以及判断「该继续调索引/改写」还是「该上覆盖索引或缓存」的量化依据是什么(比如 rows × 单行代价的阈值)?
期望答案形态:能给出 1) 一个可复现的判断口诀或代价模型;2) 针对 IN 多值 + ORDER BY 的几种改写对比与适用条件;3) 如果确实无解,推荐的兜底方案排序。