当前位置:首页 >  站长 >  建站经验 >  正文

LIMIT 100000,20慢到超时?MySQL深分页的三种解法

 2026-08-31 09:09  来源: 互联网   我来投稿 撤稿纠错

  一键部署OpenClaw

后台导出、爬虫采集、或者用户把列表翻到几千页——只要LIMIT的偏移量上了十万,查询就会肉眼可见地卡。很多人以为是数据太多撑不住,其实是MySQL的工作方式太老实:LIMIT 100000,20的意思是把前100020行都取出来,扔掉前100000行,只返回20行。偏移量越大,白干的活越多。

先复现确认:同样的查询,LIMIT 0,20毫秒级,LIMIT 500000,20十几秒,基本可以确诊深分页问题。

-- 慢的写法:偏移量越大越慢
SELECT id, title FROM articles
ORDER BY id DESC
LIMIT 500000, 20;
-- 实际扫描了50万零20行,扔掉50万行

解法一:游标分页,记住上一页最后一条的id,下一页从它之后取。这是根治方案,性能跟页码无关,翻到第几页都是毫秒级。

-- 游标分页:记住上一页末尾id=98765
SELECT id, title FROM articles
WHERE id < 98765
ORDER BY id DESC
LIMIT 20;
-- 永远只扫20行,翻到十万页也一样快

游标分页的局限是只能“上一页下一页”,跳页就废了。后台管理需要跳页的场景用解法二:延迟关联。先用覆盖索引把目标id找出来,再回表取整行数据,白干的活从“扫全行”降到“扫索引”。

-- 延迟关联:子查询只走索引
SELECT a.id, a.title, a.content
FROM articles a
JOIN (
SELECT id FROM articles
ORDER BY id DESC
LIMIT 500000, 20
) t ON a.id = t.id;
-- 子查询扫的是主键索引,比扫整行便宜一个量级

验证用EXPLAIN:延迟关联版本的执行计划里子查询应该显示Using index(覆盖索引),对比直接查询的rows估算值,差几个数量级就说明优化生效。

解法三最朴素:限制翻页深度。产品层面只允许翻前100页,再往后让用户用筛选或搜索定位。Google也只给你看前几十页,没人真需要第50000页的第3条数据。

我的排序建议:面向用户的前台直接上游标分页,一劳永逸;后台导出用延迟关联加limit分段;实在没条件改代码,就把max偏移量限制住。别让一条深分页SQL占着连接耗几十秒,它一个人就能把连接池拖垮。

数据来源:MySQL官方手册

申请创业报道,分享创业好点子。点击此处,共同探讨创业新机遇!

相关标签
php教程
mysql

相关文章

  • 千万级大表加索引不敢动?Online DDL和pt-online-schema-change实测

    大表加索引是站长的经典恐惧:ALTERTABLE一执行,表被锁住,网站瞬间打不开,KILL掉还要回滚几小时。以前确实是这样,MySQL5.6之后OnlineDDL成熟了,加索引这类操作可以在线做,执行期间允许并发读写。但“可以在线”不等于“随便什么时候都行”,坑还是有的。OnlineDDL的原理:操

    标签:
    php教程
    mysql
  • 读多写少的站,主从复制加读写分离,一台变三台

    资讯类、内容站的流量特点很一致:读请求是写请求的几十上百倍。一台MySQL扛不住时,主从复制把读压力分给从库,主库专心写,是最省钱的扩容路径——不用换机器、不用改表结构,加从库就行。前提是主从复制先搭好(这个之前写过:主库开binlog、建同步账号,从库CHANGEMASTERTO)。复制跑通后,剩

    标签:
    php教程
    mysql
  • 容器删了数据就没了?Docker卷的备份恢复,别等出事才想起来

    用Docker跑MySQL的站长,最该问自己的一个问题:数据库文件现在能被备份脚本摸到吗?数据在卷(volume)里,如果卷是匿名卷、或者备份脚本只tar了网站目录,那数据库其实处于裸奔状态,容器一坏就只能恢复到上次手动导出的时点。先搞清楚自己的数据在哪。Docker存数据两种方式:bindmoun

    标签:
    php教程
    mysql
  • docker pull龟速还磁盘报警?镜像加速和空间清理一次讲清

    Docker用久了两大顽疾:拉镜像慢得像挂了,以及/var/lib/docker目录悄悄吃掉几十G直到磁盘写满、整站报错。这两件事都有标准解法,十分钟配完。先说拉取慢。DockerHub在国内直连基本不可用,需要配镜像加速器。各家云厂商都提供免费加速地址,阿里云的控制台里有一串专属地址,填到daem

    标签:
    php教程
  • 容器启动顺序乱成一锅粥?Compose依赖、健康检查和一键启停

    站稍微复杂一点,容器就不止三个:Web、PHP、MySQL、Redis,再加个定时任务的容器。用dockerrun一个个敲,重启顺序错一次就一堆报错——PHP比MySQL先起来,连接失败直接崩。Compose的价值就是把这套依赖关系写进配置,一键按正确顺序拉起。关键是depends_on加健康检查。

    标签:
    php教程

热门排行

信息推荐