1. 千万级 MySQL 分页查询超时现场还原
先说触发点:一个交易订单管理后台,表里实际存量 1800 多万行,某天晚上运营反馈说“订单查询页面第 3 万页以后基本打不开”。抓了线上慢查询日志,有一条 SQL 稳定执行 7 秒以上,再往后翻甚至 15 秒,客户端直接报网关超时。这条 SQL 看起来人畜无害,就是一个常规的分页查询加上一个业务类型过滤,但问题就出在 MySQL 的 offset 深翻页逻辑上。
我当时第一反应也是“加个索引就好了”,但真正做完一轮优化后发现,索引只能把 7 秒压到几百毫秒,要稳定到 10ms 级别,必须把分页方式本身改掉。如果你手头也有千万级数据表的分页慢查询,或者面试中被人问过 MySQL 深分页怎么优化,这篇记录应该能给你一条可以直接落地的优化路径。
表结构其实不复杂,核心字段大致如下:
sql复制CREATE TABLE `t_trade_order` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`order_no` varchar(32) NOT NULL,
`user_id` bigint unsigned NOT NULL,
`biz_type` tinyint unsigned NOT NULL COMMENT '业务类型:1 现金交易 2 退款…',
`order_status` tinyint unsigned NOT NULL,
`amount` decimal(12,2) NOT NULL,
`pay_time` datetime DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_biz_type` (`biz_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
线上订单按业务类型做了索引,也就是 idx_biz_type。页面传入第 35001 页,每页 20 条,业务代码就把页码换算成 offset,最终执行的 SQL 长这样:
sql复制SELECT id, order_no, user_id, biz_type, order_stat
