当前位置:首页 > mysql > 正文内容

mysql中排序和分页出现重复数据

phpmianshi4年前 (2017-06-03)mysql67

场景

我们使用分页查询时候经常会遇到需要对某个或者某几个字段进行排序,在排序字段有相同值的情况下有可能最后的排序结果不是我们预期的样子,我们来看下一个例子。

表里面的rec_time列的数据是有重复的,一般情况下我们分页的sql是这样的。
第1页

select * from ugc_keyword WHERE 1 order by rec_time desc LIMIT 0,10;

结果如下:

2610    teacher_general    warning    中国病毒    2021-04-24 17:46:54    yes    0
2609    general    warning    中国病毒    2021-04-24 17:46:44    yes    0
2608    teacher_general    warning    黄牛    2021-04-24 16:53:18    yes    0
2607    teacher_letter    warning    黄牛    2021-04-24 16:51:26    yes    0
2606    letter    warning    黄牛    2021-04-24 16:47:07    yes    0
2605    express    forbid    微信    2021-04-23 22:36:55    yes    0
2604    express    forbid    公众号    2021-04-23 22:30:00    yes    0
2603    express    forbid    app    2021-04-23 22:29:24    yes    0
2544    teacher_letter    warning    176    2021-04-23 18:27:42    yes    0
2542    teacher_letter    warning    185    2021-04-23 18:27:42    yes    0

第2页

select * from ugc_keyword WHERE 1 order by rec_time desc LIMIT 10,10;

结果如下:

2546    teacher_letter    warning    171    2021-04-23 18:27:42    yes    0
2554    teacher_letter    warning    177    2021-04-23 18:27:42    yes    0
2544    teacher_letter    warning    176    2021-04-23 18:27:42    yes    0
2545    teacher_letter    warning    1709    2021-04-23 18:27:42    yes    0
2552    teacher_letter    warning    189    2021-04-23 18:27:42    yes    0
2551    teacher_letter    warning    181    2021-04-23 18:27:42    yes    0
2540    teacher_letter    warning    155    2021-04-23 18:27:42    yes    0
2550    teacher_letter    warning    180    2021-04-23 18:27:42    yes    0
2553    teacher_letter    warning    1700    2021-04-23 18:27:42    yes    0
2547    teacher_letter    warning    166    2021-04-23 18:27:42    yes    0

可以发现,id为2544的这条数据出现在了第1页和第2页当中,这样就不是我们预期当中的结果。
那这是为什么呢?

分析

在我们以往的经验和理解当中,这里应该是先进行order by排好序,然后再取对应的分页数据。其实在mysql当中并不是这样的,通过查阅官方文档可以发现在mysql中会对limit优化,我们提取最重要的信息:

大概的意思就是 如果在ORDER BY列中有多个行具有相同的值,服务器可以自由地以任何顺序返回这些行,而且根据总体执行计划的不同,返回顺序也可能不同。换句话说,这些行对于非有序列的排序顺序是不确定的。影响执行计划的一个因素是LIMIT,因此带有或不带有LIMIT的ORDER BY查询可能会返回不同顺序的行。

通过以上信息我们就可以分析出,因为排序的字段是rec_time,这个字段的值是具有相同的值的,所以返回的行是随机的。所以不同的页面出现了重复数据

解决方式

官方的解决方式:

大概的意思就是 如果确保具有或不具有LIMIT的相同行顺序很重要,那么在order BY子句中包括额外的列,以使顺序具有确定性,例如id值是唯一的。

那么新增一个排序字段id,因为在表中id是有序唯一的,所以把查询sql修改为

select * from ugc_keyword WHERE 1 order by rec_time desc,id desc LIMIT 0,10;


版权声明:本文由PHP面试资料网发布,如需转载请注明出处。
分享给朋友:

相关文章

InnoDB体系结构及工作原理

InnoDB体系结构及工作原理

概念InnoDB主要包括了内存池、后台线程以及存储文件。INNODB的三大特性:插入缓存,两次写,自适应hash内存池又是由多个内存块组成的,主要包括Buffer Pool、redo log缓冲等,解...

mysql中Query语句优化基本思路和原则

基本思路和原则在分析如何优化 MySQL Query 之前,我们需要先了解一下 Query 语句优化的基本思路和原则。一般来说,Query 语句的优化思路和原则主要体现在以下几个方面: 1. 优化更需...

innodb中统计数据是如何收集的

InnoDB 统计数据如何查看    1. 通过SHOW TABLE STATUS可以看到关于表的统计数据    2....

mysql中index_merge索引合并优化

前言深入理解 index merge 是使用索引进行优化的重要基础之一。理解了 index merge 技术,我们才知道应该如何在表上建立索引。MySQL在分析执行计划时发现走单个索引的过滤效果都不是...

mysql中长事务详解

什么是长事务运行时间比较长,长时间未提交的事务,也可以称之为大事务。这类事务往往会造成大量的阻塞和锁超时,容易造成主从延迟,要尽量避免使用长事务。下面我将演示下如何开启事务及模拟长事务:#假设我们有一...

mysql中数据页的相关概念

mysql中数据页的相关概念

概念在 InnoDB 存储引擎中,所有的数据都被逻辑地存放在表空间中,表空间(tablespace)是存储引擎中最高的存储逻辑单位,在表空间的下面又包括段(segment)、区(extent)、页(p...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。