系统城装机大师 - 固镇县祥瑞电脑科技销售部宣传站!

当前位置:首页 > 数据库 > Mysql > 详细页面

order by + limit分页时数据重复问题及解决方法

时间:2023-03-19来源:系统城装机大师作者:佚名

问题描述:MYSQL version 5.6.8command 表结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
CREATE TABLE
 
command
 
(
 
ID INT NOT NULL,
 
NAME VARCHAR(16),
 
DESCRIPTION VARCHAR(32),
 
INDEX idx_command_id (ID)
 
)
 
ENGINE=InnoDB DEFAULT CHARSET=utf8;

表数据

order by + limit分页查询

查询第1页

1 select * from command order by age limit 0,4;

查询第2页

1 select * from command order by age limit 4,4;

可以看到第2页中查出了第1页中存在的重复数据

原因分析:

查看以上语句的执行计划

可以看到,order by limit时Mysql会进行优化,使用的是内存中的filesort文件排序,in memory filesort 使用的是优先级队列(priority queue),优先级队列使用的二叉堆;

使用 priority queue 的目的,就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可这样虽然不能解决所有记录都需要排序的开销,但是只需要 sort buffer 少量的内存就可以完成排序。

 

因此,在limit n时,只会堆排序前n个,且是不稳定排序,因此并不能保证字段值相同时的相对顺序,因此分页时可能造成重复;

MySQL 5.5 没有这个优化,所以也就不会出现这个问题,5.6版本之后才出现了这种情况。

解决方案:

1. 新加一个排序字段,这个字段绝对有序,在第1个排序字段重复时, 使用第2个字段排序

2. 利用索引的有序性,如给id加上主键约束,排序字段添加索引

1 explain select id,age from command order by age limit 4,4

可以看到查询走了索引,排序就稳定了,没什么问题

(3)一些常见的数据库排序问题

不加order by的时候的排序问题
用户在使用Oracle或MySQL的时候,发现MySQL总是有序的,Oracle却很混乱,这个主要是因为Oracle是堆表,MySQL是索引聚簇表的原因。

所以没有order by的时候,数据库并不保证记录返回的顺序性,并且不保证每次返回都一致的。

分页问题

分页重复的问题

如前面所描述的,分页是在数据库提供的排序功能的基础上,衍生出来的应用需求,数据库并不保证分页的重复问题。

分享到:

相关信息

  • Mysql存储二进制对象数据问题

    Mysql存储二进制对象数据 首先数据库存储一个Object对象 与数据库对应的实体类 编写一个操作二进制的工具类 Mysql存储二进制大型对象类型对照 MySql MediumBlob——MySql的Bolb四种类型...

    2023-03-15

  • MySQL5.7升级MySQL8.0的完整卸载与安装及连接Navicat的步骤

    1、卸载MySQL5.7.24 1.备份整个数据库文件 2.停止MySQL服务 3.控制面板卸载程序 4.删除系统隐藏文件夹中的相应目录 5.清理注册表 2、安装MySQL8.0.28 3、连接Navicat...

    2023-03-15

系统教程栏目

栏目热门教程

人气教程排行

站长推荐

热门系统下载