mysql - limit

上周,我在一个项目中使用MySQL的LIMIT子句进行了编号查询。
我记得在user_info表中,我使用LIMIT 1 0, 2 0来获取1 1 到3 0条记录。
这让我可以快速看到中间数据,非常方便。

2 02 3 年,我的朋友正在学习数据库,我教他LIMIT和OFFSET的区别。
他说他现在记得LIMIT直接限制行数,而OFFSET则设置偏移量。

我的朋友还问我,如果一个表中有1 000条记录,他想知道第5 0条到第1 00条记录怎么写。
我告诉他使用 LIMIT 5 0, 5 0。

我之前想到了别的事情。
在大型表上使用 LIMIT 子句时,确实需要注意性能问题。
上次我们公司使用LIMIT 1 000, 0查询一张大表时,由于偏移量过大,数据库响应非常慢。

你必须考虑一下。
如果你遇到同样的问题,记得优化页面查询。

mysql limit的用法

LIMIT 取第一个元素。

检查号码。

对于分页,每页有 1 0 个元素。

OFFSET太大的话会很慢。

排序依据是强制性的。

自己掂量一下。

小心避坑:MySQL分页时使用 limit+order by 会出现数据重复问题

复制MySQL页面数据; 5 .6 +散装分选锅。

堆排序不稳定,相等值无效。

解决方案: 1 . 通过添加唯一字段(例如 ID)进行排序。
2 . 输入标签以对字段进行排序。

不要相信那些理论,改用 SQL。

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

哎呀,你的问题是对的!当MySQL使用LIMIT时,尤其是高偏移量的分页时,性能会受到很大影响。
让我告诉你我曾经陷入的陷阱和我看到的真实情况:
---
上周一位客户问我,他们的系统使用LIMIT进行分页,数百条数据减慢了响应时间。
我查了一下,发现LIMIT直接写成1 00000、2 0,当数据量增大时就崩溃了。

我陷入的陷阱是在 1 亿级时钟上执行此操作。
我想查看第3 页的数据,将LIMIT设置为1 0000、5 0,结果服务器CPU增加到2 00%。
我最终发现磁盘 I/O 阻碍了我。

---
为什么大偏移会成为问题?让我向您解释一下:
1 全表扫描+回表操作 想想LIMIT 3 00000, 5 是如何工作的:MySQL首先需要找到所有满足条件的记录(例如索引中的5 2 4 2 8 8 2 条记录),然后从记录3 00001 开始,根据索引中的主键ID找到聚集索引中对应的行。
最后,它只给你5 个数据,但它必须从磁盘中取出前3 00,000个数据,然后将其丢弃。

具体场景:当我在上海的一个购物中心做一个项目时,测试表只有1 000万条条目,但如果我写LIMIT 5 00000, 1 0,每个查询应该向磁盘分页5 0001 0次。
对聚集索引的访问是完全随机的,并且磁盘寻道时间被完全填满。

2 BufferPool被污染 这是特别烦人的。
大偏移量查询会将大量不重要的数据页放入BufferPool中,从而遗漏了访问非常频繁的重要数据。
我在北京的一个电商项目上看到的。
优化前,BufferPool的成功率下降到3 0%,优化后提高到9 0%。
数据页被换入换出,CPU 占用内存,因此查询自然很慢。

---
该怎么办?我个人体验优化的方法有以下几种:
1 .重写查询逻辑 使用子查询或JOIN先获取主键,然后将其返回到表中。
比如你举的例子: 平方米 从头部内部连接中选择( 从测试中选择 id WHEREval=4 LIMIT 3 00000, 5 ) b ON a.id = b.id; 这样,表只返回了 5 次,而不是 3 00005 次,并且 BufferPool 的使用量也减少了(我实际测量从 4 09 8 页减少到 5 页)。

2 光标分页 我经常使用这个技巧。
记录上一次查询的最大ID,下次检查WHERE id > last_id LIMIT 1 0例如: 平方米 从测试中选择,其中 id > 1 005 00000 LIMIT 1 0; 优点是索引扫描是顺序的,不会发生随机I/O。
缺点是应用层必须自己维护这个last_id。
我在深圳的一个项目中使用它,分页查询从5 秒下降到0.1 秒。

3 覆盖指数 如果您只需要几个字段,请将字段添加到索引中。
例如,您只需要 id 和 val: 平方米 SELECT id, val FROM test WHEREval=4 LIMIT 3 00000, 5 ; 这样索引就完成了数据,不需要返回表。

4 避免使用大的应用程序级偏移量 后端直接使用LIMIT 1 00000、1 0等,前端必须为每个页面再次运行它。
可以设计让前端传递当前页码和页面大小页面和后端自行计算偏移量。

---
实验数据供大家参考:
原始查询:SELECT FROM test WHEREval=4 LIMIT 3 00000, 5 在我的测试环境中耗时1 5 .9 8 秒,加载了4 09 8 页数据。
优化后:切换为JOIN写入方式,耗时0.3 8 秒,只加载了5 页数据。

---
总结一下我的观点:
大偏移量的根本问题是扫描了太多无用数据,导致随机 I/O 突发和 BufferPool 污染。
解决办法是:
如果不需要偏移量,就不要使用它,例如使用光标进行分页。

使用JOIN或子查询先定位主键
添加覆盖索引以避免表返回
别傻傻的往后端推送大量数据
这些方法我在多个项目中测试过,在数据量大的场景下效果尤其明显。
但请注意,每个数据库版本和存储引擎(例如 InnoDB 或 MyISAM)的性能可能会因您的环境而异。