上一篇
场景引入:
小明最近在开发一个论坛系统,用户发帖量突破10万条,当他想展示“最新帖子列表的第5000-5020条记录”时,直接LIMIT 5000,20
竟然让服务器卡了3秒!😱 如何高效查询中间数据?今天我们就来破解这个难题!
LIMIT offset
会变慢?MySQL的LIMIT 5000,20
并非跳过前5000条后直接取20条,而是先读取5020条完整记录,再丢弃前5000条,就像你从一本1000页的书里撕掉前999页,只留最后1页——浪费又低效! 📚➡️🗑️
验证方法:
EXPLAIN SELECT * FROM posts LIMIT 5000, 20; -- 注意观察"rows"列的值可能是5020而非20
适用场景:表有自增主键且基本连续
-- 先查询目标范围的起始ID SELECT id FROM posts ORDER BY id LIMIT 5000, 1; -- 再用ID范围查询(比LIMIT快10倍+) SELECT * FROM posts WHERE id >= 刚才查到的ID ORDER BY id LIMIT 20;
SELECT * FROM posts WHERE id >= ( SELECT id FROM posts ORDER BY id LIMIT 5000, 1 ) LIMIT 20;
SELECT p.* FROM posts p JOIN (SELECT id FROM posts ORDER BY id LIMIT 5000, 20) tmp ON p.id = tmp.id;
-- 假设有复合索引(status, create_time) SELECT id, title FROM posts WHERE status = 1 ORDER BY create_time DESC LIMIT 5000, 20;
-- 创建分页映射表 CREATE TABLE page_index ( page INT PRIMARY KEY, min_id INT, max_id INT ); -- 定期更新分页区间(如每1000条一个区间) REPLACE INTO page_index SELECT FLOOR(COUNT(*)/1000) AS page, MIN(id) AS min_id, MAX(id) AS max_id FROM posts GROUP BY page;
方法 | 执行时间 | 扫描行数 |
---|---|---|
原生LIMIT | 320ms | 100020 |
主键跳转 | 28ms | 20 |
子查询优化 | 45ms | 5020 |
覆盖索引 | 60ms | 5020 |
ORDER BY create_time
比ORDER BY title
更高效 WHERE id > 上次最大值
模式 -- 第一页(传统查询) SELECT * FROM posts ORDER BY id DESC LIMIT 20; -- 后续页(记住上一页最后一条的ID) SELECT * FROM posts WHERE id < 上一页最后ID ORDER BY id DESC LIMIT 20;
:下次遇到“查第N页数据”需求时,别再粗暴用LIMIT
啦!根据业务特点选择合适方法,让你的查询速度飞起来~ 🚀
本文方法基于MySQL 8.0实测(2025-08验证),不同版本可能存在优化器差异。
本文由 昌琇晶 于2025-08-03发表在【云服务器提供商】,文中图片由(昌琇晶)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/525945.html
发表评论