MySQL · 答疑解惑 · MySQL Sort 分页

简介: 背景 6.5号,小编在 Aliyun 的论坛中发现一位开发者提的一个问题,说 RDS 发现了一个超级大BUG,吓的小编一身冷汗 = =!! 赶紧来看看,背景是一个RDS用户创建了一张表,在一个都是NULL值的非索引字段上进行了排序并分页,用户发现第二页和第一页的数据有重复,然后以为是NULL

背景

6.5号,小编在 Aliyun 的论坛中发现一位开发者提的一个问题,说 RDS 发现了一个超级大BUG,吓的小编一身冷汗 = =!!
赶紧来看看,背景是一个RDS用户创建了一张表,在一个都是NULL值的非索引字段上进行了排序并分页,用户发现第二页和第一页的数据有重复,然后以为是NULL值的问题,把这个字段都更新成相同的值,发现问题照旧。详细的信息可以登录阿里云的官方论坛查看

小编进行了尝试,确实如此,并且5.5的版本和5.6的版本行为不一致,所以,必须要查明原因。

原因调查

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

while (get_next_sortkey())
     {
       if (using priority queue)
         push sort key into queue
       else
       {
         if (no free space in sort_keys buffers)
         {
           sort sort_keys buffer;
           dump sorted sequence to 'tempfile';
           dump BUFFPEK describing sequence location into 'buffpek_pointers';
         }
         put sort key into 'sort_keys';
       }
     }
     if (sort_keys has some elements && dumped at least once)
       sort-dump-dump as above;
     else
       don't sort, leave sort_keys array to be sorted by caller.

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

之所以5.6出现了第二页数据重复的问题,是因为 priority queue 使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法,也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。

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

解决方法

1. 索引排序字段
之前的月报中,我们讨论过三星索引的设计,其中第二条就是利用索引的有序性,如果用户在字段添加上索引,就直接按照索引的有序性进行读取并分页,从而可以规避遇到的这个问题。

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

分页一直都有这个问题,我们看分页常用的场景:1)早期的论坛 2)个人交易记录。这些场景都对数据分页都没有非常高的准确性要求。

究竟是不是BUG

究竟归于bug问题还是用户使用理解上的问题?

小编觉得应该分开看待这个问题,如果是排序的问题,那就算是BUG,如果是分页的这个问题,那它确实完成了order by的功能,也完成了limit n功能,那就不能说它是BUG,分页就纯粹变成了用户理解的问题了。

用户在使用数据库的时候常见的一些问题:

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

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

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


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
关系型数据库 MySQL 索引
17. MYSQL超大分页怎么处理 ?
`MYSQL`超大分页效率低,因为实际是获取`offset+N`行再丢弃前`offset`行。解决方法:先通过索引快速定位所需ID,然后进行关联查询获取数据,以提高性能。
244 0
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
Mybatis+mysql动态分页查询数据案例——分页工具类(Page.java)
|
11月前
|
SQL 缓存 关系型数据库
如何解决MySQL 的深度分页问题?
在构建高性能Web应用程序时,数据库查询性能至关重要。本文深入探讨了MySQL中`LIMIT ... OFFSET ...`语法的性能瓶颈,并介绍了一种更高效的分页方法——游标分页(Cursor Pagination)。通过记录每页最后一个记录的唯一标识,游标分页能显著提升查询效率,将时间复杂度从O(n + m)降低到O(log n + m),特别适用于大规模数据的分页查询场景。此外,文章还介绍了其他优化方法,如覆盖索引分页、分区表、缓存和基于时间戳的分页,并提供了实践中的最佳建议,帮助开发者选择最适合的分页策略,提升系统性能和用户体验。
695 9
|
7月前
|
存储 SQL 关系型数据库
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
京东面试:mysql深度分页 严重影响性能?根本原因是什么?如何优化?
|
存储 关系型数据库 MySQL
mysql数据库查询时用到的分页方法有哪些
【8月更文挑战第16天】在MySQL中,实现分页的主要方法包括:1)使用`LIMIT`子句,简单直接但随页数增加性能下降;2)通过子查询优化`LIMIT`分页,提高大页码时的查询效率;3)利用存储过程封装分页逻辑,便于复用但需额外维护;4)借助MySQL变量实现,可能提供更好的性能但实现较复杂。这些方法各有优缺点,可根据实际需求选择适用方案。
1041 2
|
10月前
|
监控 关系型数据库 MySQL
MySQL和SQLSugar百万条数据查询分页优化
在面对百万条数据的查询时,优化MySQL和SQLSugar的分页性能是非常重要的。通过合理使用索引、调整查询语句、使用缓存以及采用高效的分页策略,可以显著提高查询效率。本文介绍的技巧和方法,可以为开发人员在数据处理和查询优化中提供有效的指导,提升系统的性能和用户体验。掌握这些技巧后,您可以在处理海量数据时更加游刃有余。
926 9
|
关系型数据库 MySQL PHP
php实现一个简单的MySQL分页
通过本文的详细步骤和代码示例,我们实现了一个简单的PHP MySQL分页功能。主要步骤包括计算总记录数、设置分页参数、查询当前页的数据以及生成分页链接。这种分页方式适用于大多数Web应用,能够有效提升用户体验和页面响应速度。
297 4
|
SQL 关系型数据库 MySQL
mysql分页读取数据重复问题
在服务端开发中,与MySQL数据库进行数据交互时,常因数据量大、网络延迟等因素需分页读取数据。文章介绍了使用`limit`和`offset`参数实现分页的方法,并针对分页过程中可能出现的数据重复问题进行了详细分析,提出了利用时间戳或确保排序规则绝对性等解决方案。
505 1
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
算法 关系型数据库 MySQL
MySQL高级篇——排序、分组、分页优化
排序优化建议、案例验证、范围查询时索引字段选择、filesort调优、双路排序和单路排序、分组优化、带排序的深分页优化
MySQL高级篇——排序、分组、分页优化

相关产品

  • 云数据库 RDS MySQL 版
  • 推荐镜像

    更多