

新闻资讯
技术学院MySQL大数据量分页慢本质是OFFSET越大扫描行数越多;应改用游标分页,即记录上页末条排序值,下页查大于该值的记录,并避免SQL_CALC_FOUND_ROWS及依赖ID连续性。
MySQL大数据量分页查询慢,本质是OFFSET 越大,扫描行数越多。比如 SELECT * FROM t ORDER BY id LIMIT 1000000, 20,MySQL 仍需先跳过前100万行,再取20条——这过程不走索引优化,I/O 和 CPU 开销陡增。真正有效的优化不是“加索引”就完事,而是绕开 OFFSET 的低效机制。
适合按时间、ID 等单调字段排序的场景(如最新订单、文章列表)。核心是“记住上一页最后一条的排序值”,下一页直接查“大于该值”的记录。
SELECT * FROM orders ORDER BY created_at DESC LIMIT 10000, 20
SELECT * FROM orders WHERE created_at ,前提是上一页最后一条的 created_at 是这个时间
id 防止时间重复)当需要分页返回大量字段,但排序/过滤只依赖少量字段时,先用覆盖索引快速定位 ID,再关联原表取数据。
user_id 排序查用户详情SELECT u.* FROM users u INNER JOIN (SELECT id FROM users ORDER BY user_id LIMIT 100000, 20) t ON u.id = t.id
INDEX(user_id)),不读全行;外层再按 ID 主键回表,效率远高于全字段扫描SELECT * 在子查询中单表超 5000 万行后,即使优化 SQL,维护成本和查询抖动仍高。可按时间(如月表 orders_202505)或哈希(如 user_id % 16)拆分,分页请求由应用层计算落到哪张子表。
LIMIT 10000,20 变成轻量操作last_id 和 table_suffix)有些“看似优化”的做法实际无效甚至更差:
WHERE id > ? ORDER BY id LIMIT 20:若 ID 不连续(删过数据),会跳过记录,造成分页漏数SQL_CALC_FOUND_ROWS:获取总页数仍要全表扫描,大数据下比直接 COUNT(*) 还慢EXPLAIN 的 rows
× 抽样比例)FORCE INDEX(idx_created_at) 防止优化器选错执行计划