Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >如何解决MySQL order by limit语句的分页数据重复问题?

如何解决MySQL order by limit语句的分页数据重复问题?

作者头像
好好学java
发布于 2021-04-30 03:51:27
发布于 2021-04-30 03:51:27
3.1K00
代码可运行
举报
运行总次数:0
代码可运行

0 问题描述

MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。

但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一页的记录。

具体如下:

代码语言:javascript
代码运行次数:0
复制
SELECT `post_title`,`post_date` FROM post WHERE `post_status`='publish' ORDER BY view_count desc LIMIT 5,5
代码语言:javascript
代码运行次数:0
复制

使用上述SQL查询的时候,很有可能出现和LIMIT 0,5相同的某条记录。而如果使用如下方式,则不会出现重复的情况:

代码语言:javascript
代码运行次数:0
复制
SELECT * FROM post WHERE post_status='publish' ORDER BY view_count desc LIMIT 5,5
代码语言:javascript
代码运行次数:0
复制

但是,由于post表的字段很多,仅仅希望用这两个字段,不想把post_content也查出来。

为了解决这个情况,在ORDER BY后面使用了两个排序条件来解决这个问题,如下:

代码语言:javascript
代码运行次数:0
复制
SELECT `post_title`,`post_date` FROM post WHERE `post_status`='publish' ORDER BY view_count desc,ID asc LIMIT 5,5

按理来说,MySQL的排序默认情况下是以主键ID作为排序条件的

也就是说,如果在view_count相等的情况下,主键ID作为默认的排序条件,不需要我们多此一举加ID asc。

但是事实就是,MySQL再order by和limit混用的时候,出现了排序的混乱情况。

1 分析问题

在MySQL 5.6的版本上,优化器在遇到order by limit语句的时候,做了一个优化,即使用了priority queue。

使用 priority queue 的目的,就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可

这样虽然不能解决所有记录都需要排序的开销,但是只需要 sort buffer 少量的内存就可以完成排序。

之所以MySQL 5.6出现了第二页数据重复的问题,是因为 priority queue 使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法

也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。

MySQL 5.5 没有这个优化,所以也就不会出现这个问题。

也就是说,MySQL 5.5是不存在本文提到的问题的,5.6版本之后才出现了这种情况。

再看下MySQL解释sql语言时的执行顺序:

代码语言:javascript
代码运行次数:0
复制
(1)     SELECT
(2)     DISTINCT <select_list>
(3)     FROM <left_table>
(4)     <join_type> JOIN <right_table>
(5)     ON <join_condition>
(6)     WHERE <where_condition>
(7)     GROUP BY <group_by_list>
(8)     HAVING <having_condition>
(9)     ORDER BY <order_by_condition>
(10)    LIMIT <limit_number>
代码语言:javascript
代码运行次数:0
复制

执行顺序依次为 form… where… select… order by… limit…

由于上述priority queue的原因,在完成select之后,所有记录是以堆排序的方法排列的

在进行order by时,仅把view_count值大的往前移动。但由于limit的因素,排序过程中只需要保留到5条记录即可

view_count并不具备索引有序性,所以当第二页数据要展示时,mysql见到哪一条就拿哪一条

因此,当排序值相同的时候,第一次排序是随意排的,第二次再执行该sql的时候,其结果应该和第一次结果一样。

2 解决方法

(1)索引排序字段

如果在字段添加上索引,就直接按照索引的有序性进行读取并分页,从而可以规避遇到的这个问题。

(2)正确理解分页

分页是建立在排序的基础上,进行了数量范围分割。排序是数据库提供的功能,而分页却是衍生的出来的应用需求。 在MySQL和Oracle的官方文档中提供了limit n和rownum < n的方法,但却没有明确的定义分页这个概念。 还有重要的一点,虽然上面的解决方法可以缓解用户的这个问题,但按照用户的理解,依然还有问题 比如,这个表插入比较频繁,用户查询的时候,在read-committed的隔离级别下,第一页和第二页仍然会有重合。 所以,分页一直都有这个问题,不同场景对数据分页都没有非常高的准确性要求。

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

不加order by的时候的排序问题

用户在使用Oracle或MySQL的时候,发现MySQL总是有序的,Oracle却很混乱,这个主要是因为Oracle是堆表,MySQL是索引聚簇表的原因。 所以没有order by的时候,数据库并不保证记录返回的顺序性,并且不保证每次返回都一致的。

分页问题 分页重复的问题

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

NULL值和空串问题

不同的数据库对于NULL值和空串的理解和处理是不一样的 比如Oracle NULL和NULL值是无法比较的,既不是相等也不是不相等,是未知的。 而对于空串,在插入的时候,MySQL是一个字符串长度为0的空串,而Oracle则直接进行NULL值处理。

代码语言:javascript
代码运行次数:0
复制
推荐文章面试官问:前后端分离项目,有什么优缺点?我说:没
2020 年腾讯新增 20 亿行代码,鹅厂第一编程语言还是它
通俗讲解分布式锁,看完不懂算我输
写博客能月入10K?
一款基于 Spring Boot 的现代化社区(论坛/问答/社交网络/博客)更多项目源码
这或许是最美的Vue+Element开源后台管理UI推荐一款高颜值的 Spring Boot 快速开发框架
一款基于 Spring Boot 的现代化社区(论坛/问答/社交网络/博客)
13K点赞都基于 Vue+Spring 前后端分离管理系统ELAdmin,大爱想接私活时薪再翻一倍,建议根据这几个开源的SpringBoot项目
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好好学java 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
如何解决MySQL order by limit语句的分页数据重复问题?
在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。
JAVA葵花宝典
2021/04/08
1.4K0
mysql 5.6 order by limit 排序分页数据重复问题
https://mariadb.com/kb/en/filesort-with-small-limit-optimization/
明明如月学长
2021/08/31
1.1K0
mysql 5.6 order by limit 排序分页数据重复问题
select * from table order by xx limit 0,10
双面人
2020/02/11
1.4K0
浅谈MySQL分页查询的工作原理
MySQL 的分页查询在我们的开发过程中还是很常见的,比如一些后台管理系统,我们一般会有查询订单列表页、商品列表页等。
政采云前端团队
2023/11/09
2K0
浅谈MySQL分页查询的工作原理
MySQL 使用 order by limit 分页排序会导致数据丢失和重复!
作为程序员,经常写 SQL 语句是正常不过了。然而,编写一些 SQL 语句,总会出现一些奇怪的问题。
格姗知识圈
2021/02/02
6.3K0
MySQL 使用 order by limit 分页排序会导致数据丢失和重复!
MYSQL中使用order by…limit时候遇到的坑
最近遇到这样的一个奇怪的问题——SQL中排序分页的查询结果中出现了重复数据。百思不得其解,检查了代码,没有发现任何问题,但这种现象就是会出现。
SEian.G
2021/03/03
1.1K0
MySQL - 当LIMIT 进行分页时,为什么出现了重复数据
说在前面 数据库分页是后台经常要使用的技术手段,有时候进行数据库查询会根据业务需要对某一字段排序,那么当待排序字段值相同时,我们得到的查询结果会是什么呢?
双面人
2019/08/25
4.5K0
DQL-limit分页
在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?不用担心,mysql已经为我们提供了这样一个功能-limit。
星哥玩云
2022/09/15
4240
DQL-limit分页
Mysql分页order by数据错乱重复
作久项目代码优化,公司用的是Mybatis,发现分页和排序时直接传递参数占位符用的都是 $,由于$有SQL注入风险,要改为#,但是封装page类又麻烦,所以直接使用了 pageHelper 插件了,方便快捷,但是测试时发现数据有问题:
traffic
2020/04/09
2.4K0
java oracle分页查询语句_oracle 分页语句
SELECTOBJ_NAME, OBJ_ATTRIBUTE_NAME, ATTRIBUTE_TYPE, DES, STS, PRIORITY
全栈程序员站长
2022/09/01
1.5K0
MySQL 系列:注意 ORDER 和 LIMIT 联合使用的陷阱
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
Lorin 洛林
2023/12/13
5450
MySQL进阶学习之SQL优化【插入,主键,排序,分组,分页,计数】
如果一次性需要插入大批量数据(比如: 几百万的记录),使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。操作如下:
叫我阿杰好了
2022/11/07
2.2K0
MySQL进阶学习之SQL优化【插入,主键,排序,分组,分页,计数】
MySQL排序速度慢而且可能不稳定
有一个功能,按照算法得出的权重值,分页展示一批列表数据,权重值越大越靠前。研发同学反馈查询速度慢且排序不稳定。
普通程序员
2019/11/12
2.3K0
MySQL排序速度慢而且可能不稳定
MySQL | 使用 limit 优化查询和防止SQL被优化
查询优化1.1 最大值和最小值的优化1.2 优化 limit 分页1.2.1 使用关联查询优化1.2.2 使用范围查询1.2.3 利用唯一自增序列进行查询防止被优化参考
双鬼带单
2021/07/20
1.4K0
使用JDBC连接MySQL数据库--典型案例分析(八)----实现员工数据的分页查询
对于较大的数据量,通常采用分页查询的方式。不同的数据库产品有不同的数据库级的分页查询策略。例如:Oracle通常使用rownum的方式;而Mysql使用limit的方式。
MickyInvQ
2020/09/27
1.2K0
使用JDBC连接MySQL数据库--典型案例分析(八)----实现员工数据的分页查询
mysql的sql分页查询语句怎么写_sql 分页查询语句(mysql分页语句)「建议收藏」
intpageCount=15(每页显示的行数)intTotalCount=30(页数*每页显示的行数),这里是第二页stringsearchString=xxxxxx(搜索条件)selecttoppageCount*from表名whereidnotin(selecttopTotalCountidfrom表名wheresearchString)wheresearchStringorderbytimedesc然后下个aspnetpage的分页控件就行了,以上是分页的SQL语句..
全栈程序员站长
2022/07/29
13.5K0
mysql的sql分页查询语句怎么写_sql 分页查询语句(mysql分页语句)「建议收藏」
order by 原理以及优化
一 简介 偏向于业务的(MySQL)DBA或者业务的开发者来说,order by 排序是一个常见的业务功能,将结果根据指定的字段排序,满足前端展示的需求。然而排序操作也是经常出现慢查询排行榜的座上宾。本文将从原理和实际案例优化,order by 使用限制等几个方面来逐步了解order by 排序。
用户1278550
2018/08/09
7470
多数人都曾遇到过的 limit 问题,深入浅出 MySQL 优先队列
假设字段category无索引且有重复值,order by category 和limit组合使用的结果会和预期不符。
用户4172423
2020/11/04
1K0
多数人都曾遇到过的 limit 问题,深入浅出 MySQL 优先队列
玩转Mysql系列 - 第7篇:详解排序和分页(order by & limit),及存在的坑
电商中:我们想查看今天所有成交的订单,按照交易额从高到低排序,此时我们可以使用数据库中的排序功能来完成。
路人甲Java
2019/09/16
3.6K0
mysql查询 limit 1000,10 和limit 10 速度一样快吗?如果我要分页,我该怎么办?
建表sql大家也不用扣细节,只需要知道id是主键,并且在user_name建了个非主键索引就够了,其他都不重要。
小白debug
2022/06/20
1.6K0
mysql查询 limit 1000,10 和limit 10 速度一样快吗?如果我要分页,我该怎么办?
推荐阅读
相关推荐
如何解决MySQL order by limit语句的分页数据重复问题?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验