三点都踩在点上,补两个落地时最容易反噬的细节。
先说游标翻页:created_at + id 不要拆成两个独立条件,排序必须写成 ORDER BY created_at DESC, id DESC,否则同一秒发布的两条帖子在翻页边界上会重复或丢失。对应索引也得是 (board_id, status, created_at, id) 四列才算真正覆盖,少了 id 这一列仍然是 filesort,等于白改。
再说字段顺序,你讲的“范围在后”有个例外值得点出来:当范围字段和排序字段是同一个时,比如 WHERE board_id=? AND created_at > ? ORDER BY created_at,最合理的反而是把索引收窄成 (board_id, created_at),status 放进索引里也用不上,只会白白占空间、拉低缓存命中。三列还是两列,取决于 status 是不是固定的等值条件、区分度够不够,不能照搬模板。
验证环节建议优先用 EXPLAIN ANALYZE(MySQL 8.0.18 起支持),它会真正执行一遍,给出实际行数和耗时,比只看估算的 rows 可靠得多;5.7 只能靠执行前后 SHOW SESSION STATUS LIKE 'Handler_read%' 的差值来估。
最后,如果业务确实需要“跳到第 N 页”,最好给个页码上限,或者上近似计数,不要用 offset 勉强支撑。

正式会员
认证极客









