MySQL order by + limit 分页隐藏陷阱

在使用MySQL的order by + limit进行分页时,遇到加limit前后结果顺序不一致及分页数据重叠的问题。原因是当排序字段有重复值时,MySQL的limit在排序未完成时可能提前结束,导致不同结果。解决方案是增加一个唯一的排序字段,如id,以确保分页的准确性。
摘要由CSDN通过智能技术生成

MySQL通过order by + limit实现分页的时候遇到了两个问题:

  1. SQL语句加limit和不加limit返回的顺序不一致
  2. SQL语句第一页和第二页的数据出现重叠(一共就两页数据)

完整的表结构和数据见文章末尾

不带limit的SQL语句如下:

select * from album_play_stat_app_type_daily order by active_user_num desc

1、加limit和不加limit结果集顺序不一致

当不加limit的时候返回的结果集为:
在这里插入图片描述
当加了limit之后SQL语句为:

select * from album_play_stat_app_type_daily order by active_user_num desc limit 0, 10

返回结果为:
在这里插入图片描述
比较两次的SQL语句,从执行逻辑上来看,第二条SQL语句应该按照第一条SQL的结果集取前10条返回才对,但实际上却并非如此!

2、第一页和第二页的数据出现重叠

修改SQL语句查询第二页数据,SQL语句为:

select * from album_play_stat_app_type_daily order by active_user_num desc limit 10, 10;

返回值:
在这里插入图片描述
比较第一页和第二页返回的结果集,可以看到当中有三条记录出现了重叠。

3、原因

3.1、limit加与不加返回顺序不一样

当order by后面的排序字段出现重复值的时候,比如问题中的active_user_num字段,存在很多的重复值,MySQL排序的时候返回他们的顺序是不确定的;
而limit语句在执行的时候并不会等到所有的结果都排序完成之后再进行截取,而是当有序集的大小已经满足要求的时候便会结束后续操作,返回有序集;

3.2、第一页和第二页数据重叠

原因同问题1;

4、解决方案

再添加一个排序字段,比如id,保证联合排序字段唯一,修改后SQL如下:

select * from album_play_stat_app_type_daily
order by active_user_num desc, id desc

参考:MySQL 官方手册-limit查询优化

完整的表结构和数据

CREATE TABLE `album_play_stat_app_type_daily` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `app_type` tinyint(3) unsigned NOT NULL DEFAULT '1' COMMENT '应用类型',
  `album_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT '专辑ID',
  `album_title` varchar(255) CHARACTER SET utf8 NOT 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQLORDER BY语句用于对查询结果进行排序。当我们在分页查询中使用ORDER BY语句时,可能会影响查询性能,原因如下: 1. 排序操作需要消耗额外的计算资源。ORDER BY语句会对查询结果进行排序,这需要对每条记录进行比较和排序操作,消耗CPU和内存资源。 2. 排序操作可能需要使用临时表。如果查询结果集很大,MySQL可能会使用临时表来存储中间结果,然后在临时表上进行排序操作。这会增磁盘IO操作和存储开销。 3. 排序字段的索引可能无效。如果排序的字段没有相应的索引,MySQL将无法高效地进行排序操作,而是会执行全表扫描来排序结果。全表扫描会导致查询性能下降。 为了优化分页查询中的排序操作,可以考虑以下方法: 1. 使用索引覆盖查询。如果排序字段有相应的索引,并且查询的字段只包含索引字段,MySQL可以直接使用索引进行排序,避免全表扫描和临时表的使用。 2. 限制查询结果集大小。如果只需要获取前几条记录,可以使用LIMIT子句限制结果集的大小,减少排序操作的开销。 3. 避免在分页查询中频繁改变排序字段。如果每次分页查询都使用不同的排序字段,MySQL无法充分利用缓存和索引,导致性能下降。最好在分页查询中保持相同的排序字段。 总而言之,分页查询中使用ORDER BY语句可能会影响性能,但可以通过使用索引、限制结果集大小和保持相同的排序字段等方法进行优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值