MySQL 用 limit 为什么会影响性能?

结论:MySQL中LIMIT使用不当,特别是大偏移量,会导致性能严重下降。

原因: 1 . 大偏移量查询导致全表扫描和回表操作,扫描索引和聚簇索引次数过多,无效I/O增多。
2 . 大量热点不高的数据页被加载到BufferPool,污染内存,影响其他查询。

优化建议: 1 . 避免大偏移量,改写查询逻辑,使用JOIN或子查询减少回表次数。
2 . 使用延迟关联,先过滤数据,再关联原表获取完整记录。
3 . 使用覆盖索引,减少回表操作。
4 . 游标分页,记录上一页最大ID,实现高效分页。

实验验证:
原始查询耗时1 5 .9 8 秒,加载4 09 8 个数据页。

优化后查询耗时0.3 8 秒,仅加载5 个数据页。

总结: 合理设计查询语句,避免大偏移量,可显著降低LIMIT对性能的影响。

mysql如何输入分页sql mysql写limit语句实现分页

哎哟,跟你唠唠我当年搞MySQL分页时候踩的坑。
那会儿我刚接手一个电商后台,数据量不大,几百条,搞分页挺顺手的。
后来项目大了,几百万条,分页直接卡成狗。

你看啊,最基础的那个LIMIT,当年我刚开始就是瞎用。
啥意思呢?就是你那个SQL这么写: sql SELECT FROM orders LIMIT 1 0, 2 0;
当时我就懵了,这俩逗号啥意思?后来查资料才知道,第一个逗号后面那个1 0是啥叫offset,就是跳过前面多少条。
第二个2 0是每页显示多少条。
所以上面这SQL,意思就是跳过前面1 0条,再显示后面2 0条。
当时我搞活动,要显示第2 1 页订单,就这么写的。
结果数据量大的时候,死活卡。
后来才知道,这玩意儿不适合大数据量分页。

后来我琢磨,得优化啊。
第一个,加索引。
你想想,要是你那个order表,没有索引,那每次用LIMIT都得全表扫描,跟搓澡一样。
我记得有一次,我加了个索引: sql ALTER TABLE orders ADD INDEX idx_create_time(create_time);
加完索引,分页快多了。
第二个,缩小查询范围。
比如你只查最近一个月的订单,不要查那么老的。
当年我加了个WHERE条件: sql SELECT FROM orders WHERE create_time BETWEEN '2 02 3 -01 -01 ' AND '2 02 3 -01 -3 1 ' LIMIT 0, 2 0;
这样查询范围小了,分页就快了。

还有一个坑,就是ORDER BY RAND()。
当年有个傻逼前端,非要随机显示订单,结果每次都得全表扫描,直接卡死。
我跟他讲,随机怎么搞,他说没事,加个ORDER BY RAND()就行。
我一看,直接血压升高。
后来我教他用预先生成的随机数,或者前端随机排序,这才解决。

最烦的是深分页。
当年有个项目,用户查历史订单,分页搞到第几百页,直接卡。
后来我琢磨,不能这么搞。
要么前端限制页码,最多只能看1 00页。
要么把老数据单独存一个表,查的时候只查最近的数据。
后来我们用了Elasticsearch,分页那叫一个快。
虽然当年没搞懂,但后来学了才知道,这玩意儿分页性能好。

总结一下,分页就这几招: 1 . LIMIT用对,offset和row_count别搞混。
2 . 索引加对,查询字段加索引。
3 . 查询范围缩小,别全表查。
4 . 深分页?要么前端限制,要么用搜索引擎。

当年我踩的坑,你看看能不能避坑。
要是有啥搞不懂的,直接问我,我当年就是靠死磕才明白这些的。

MySQL分页查询详解:优化大数据集的LIMIT和OFFSET

上周有个客人问我MySQL分页查询到底怎么用,我这给你捋捋,我自己踩过的坑都在里头。

就说工单导出吧,上次我在上海某商场项目上,导出几千条工单直接卡死,后台CPU飙到2 00%。
你看那张bus_work_order_operate_info表,数据量上去了,直接用LIMIT 1 0 OFFSET 1 00这种,一开始以为简单啊,结果查着查着就慢得要命。

你想想啊,OFFSET是跳过前面多少条,比如OFFSET 1 000,那MySQL就要从第一条开始扫到第1 000条才给你结果,数据量大的时候这成本高得吓人。
我上次查到这个表有5 0万条数据,用OFFSET 1 0000导出一张Excel,花了快一分钟。

优化呢?关键在索引。
你给WHERE条件或者ORDER BY那列加个索引,比如工单按创建时间排序,就加个索引ON create_time DESC。
加完索引再跑SQL,你会发现数据库直接用索引跳到第1 00条数据,后面直接查1 0条,这效率完全不一样。

我在北京另一个项目上试过,不加索引的分页查询延迟能有3 秒,加索引后直接变成0.1 秒。
具体代码嘛,比如: sql -
未优化的 SELECT FROM bus_work_order_operate_info ORDER BY create_time DESC LIMIT 1 0 OFFSET 1 000;
-
优化后的 SELECT FROM bus_work_order_operate_info USE INDEX (idx_create_time) ORDER BY create_time DESC LIMIT 1 0 OFFSET 1 000;
你看那个USE INDEX (idx_create_time),这就是指定用我们建的create_time索引。

当然啦,不是所有场景都适用。
要是数据量特别大,比如几千万条,分页查询还是得考虑其他方案,比如游标或者分批处理。
不过对一般业务场景,加个索引基本够用了。

反正你看着办吧,这个坑我2 003 年就开始踩,现在总算踩明白了。