首页 > 数据库 >MYSQL分页查询时没有用ORDER BY出现数据重复的问题

MYSQL分页查询时没有用ORDER BY出现数据重复的问题

时间:2023-01-22 00:11:06浏览次数:64  
标签:顺序 分页 SQL ORDER MYSQL 主键 排序 数据 order

背景

产品反馈,用户在使用分页列表时,出现数据重复的问题,查看代码后发现对应的分页SQL并没有使用order by进行排序,但是印象中Mysql的InnoDB引擎会默认按照主键id进行排序,本地测试了一下的确出现了部分数据在不同的页都出现的问题。

于是带着问题去查阅相应的资料,发现原先的认知是错误的。

如果没有定义 order by

MySQL使用SELECT 语句不加ORDER BY默认是如何排序的

那返回的数据不一定是按照主键来排序的,结果可以以任意顺序返回 - 也可能随着时间而改变。

在关系数据库中没有“自然顺序”或类似的东西(至少在我所知道的情况下)。获得可靠排序的唯一方法是显式指定 order by子句,来源when-no-order-by-is-specified-what-order-does-a-query-choose-for-your-record

对于同样的一批数据,在某一个时刻顺序是一样的,随着时间变化,数据会发生变化,那么在进行查询的时候,MySQL 会尝试以尽可能快的方法(MySQL 实际的方法不见得快)返回数据。

由于访问主键、索引大多数情况会快一些(在Cache里)所以返回的数据有可能以主键、索引的顺序输出,这里并不会真的进行排序,主要是由于主键、索引本身就是排序放到内存的,所以连续输出时可能是某种序列。在一些情况下消耗硬盘寻道时间最短的数据会先返回。如果只查询单个表,在特殊的情况下是有规律的。

大致解读一下回答的内容,重新发布一下之前回答过的一个SQL Server类型的问题。

在 SQL 世界中,顺序不是一组数据的固有属性。因此,除非您使用 order by 子句查询您的数据,否则您无法从 RDBMS 保证您的数据将按特定顺序返回 - 甚至以一致的顺序返回。

然后回答你的问题:

•MySQL 根据需要对记录进行排序,但没有任何一致性保证•如果您打算依赖此顺序进行任何操作,则必须使用 order by 指定您想要的顺序。否则做任何其他事情都是在为不受欢迎的意外做好准备。

这是所有 SQL 的属性,而不仅仅是 MySQL。SQL-92 规范中的相关文本是:

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

如果未指定 <order by 子句>,则 Q 的行的顺序取决于底层实现。

本文的内容就是如上这些内容了,大致总结一下: 如果在使用没有指定order by,那么基本上依赖于底层实现的,具体排序规则不定,所以排序的顺序也不固定,可能会随着时间发生变化。

在实际工作中,如果有查询列表展示数据的功能和需求,开发前一定要先确定数据排序的规则,这样可以避免后续出现数据查询的排序结果不同的问题。

相关文章:

https://dba.stackexchange.com/questions/6051/what-is-the-default-order-of-records-for-a-select-statement-in-mysql

http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt

 

本篇文章如有帮助到您,请给「翎野君」点个赞,感谢您的支持。

首发链接:https://www.cnblogs.com/lingyejun/p/17064119.html

标签:顺序,分页,SQL,ORDER,MYSQL,主键,排序,数据,order
From: https://www.cnblogs.com/lingyejun/p/17064119.html

相关文章

  • readyset 轻量级pg 以及mysql 缓存引擎
    readyset是基于rust开发的pg以及mysql轻量级缓存服务参考玩法如下图  说明readyset一些设计还是很有意思的,很值得学习,同时也可以在项目中尝试使用参考资料ht......
  • c/c++ mysql api函数
    一、常用APImysql_affected_rows()返回上次UPDATE、DELETE或INSERT查询更改/删除/插入的行数。mysql_autocommit()切换autocommit模式,ON/OFFmysql_change_user()......
  • 解决Loading class `com.mysql.jdbc.Driver'. This is deprecated.
    IDEA编写的数据库报红字:Loadingclass`com.mysql.jdbc.Driver'.Thisisdeprecated.Thenewdriverclassis`com.mysql.cj.jdbc.Driver'.Thedriverisautomatical......
  • MySQL之视图
    视图什么是视图视图是一张虚表(建立在真实的table的基础之上,即视图的数据来源是对应的table).首先需要创建一张表,在表的基础上,指定的列映射成一个视图.就是一个SEL......
  • Linux中安装MySQL
    1.卸载系统自带的mariadb我这里使用的是Centos7,所以系统会自带Mariadb,需要先卸载掉,当然后面在安装mysql的过程中也会有提示查询已安装的Mariadb安装包:rpm-qa|......
  • MySQL
    DBDataBase数据库数据库分类关系型数据库(SQL),通过表和表之间,行和列之间的关系进行数据的存储MySQLOracleSqlServerDB2SQLlite非关系型数据库(NoSQL,notonl......
  • MySQL
    DBDataBase数据库数据库分类关系型数据库(SQL),通过表和表之间,行和列之间的关系进行数据的存储MySQLOracleSqlServerDB2SQLlite非关系型数据库(NoS......
  • MySQL必知必会第十四章-使用子查询
    使用子查询子查询查询(query)任何SQL语句都是查询。但此术语一般指SELECT语句。SQL还允许创建子查询(subquery),即嵌套在其他查询中的查询。利用子查询进行过滤SELECTcus......
  • MySQL索引使用宝典已送达,快来查缺补漏 转载
    这一篇文章来聊一聊如何用好MySQL索引。  为了更好地进行解释,我创建了一个存储引擎为InnoDB的表user_innodb,并批量初始化了500W+条数据。包含主键id、姓名字段(name)、......
  • Mysql8开启root远程并设置访问密码
    和旧版本设置,有点不一样mysql-urootmysql>usemysql;#查看user表信息,注意密码字段已改为autentication_stringmysql>selectuser,host,authentication_string......