MySQL 系列:注意 ORDER 和 LIMIT 联合使用的陷阱
文章目录
- 前言
- 背后的原因
- ORDER BY 排序列存在相同值时返回顺序是不固定的
- LIMIT 和 ORDER BY 联合使用时的行为
- ORDER BY 或 GROUP BY 和 LIMIT 联合使用优化器默认使用有序索引
- 如何解决
- 其它说明
- 个人简介
前言
- 不知道大家在在分页查询中有没有遇到过这个问题,分页查询中不同的页中出现了同一条数据,出现了分页错乱的问题:
- 整体排序:
SELECT * from test_1 ORDER BY create_date;
- 提取排序后的前两条:
SELECT * from test_1 ORDER BY create_date LIMIT 0,2;
- 提取排序后的最后两条:
SELECT * from test_1 ORDER BY create_date LIMIT 8,2;
- 上面的结果是不是很奇怪,按照大家正常的思考,
MySQL
对我们查询的数据进行整体排序,我们按页取出,理论上不应该在不同的页中有相同的数据,下面我们一起来看看隐藏在背后的原因。
背后的原因
- https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html
- 官网的说明内容比较多,我主要摘抄了以下几点比较相关的内容,下面我们一起来看看吧。
ORDER BY 排序列存在相同值时返回顺序是不固定的
If multiple rows have identical values in the ORDER BY columns, the server is free to return those rows in any order, and may do so differently depending on the overall execution plan. In other words, the sort order of those rows is nondeterministic with respect to the nonordered columns.
- 如果多个行在ORDER BY列中具有相同的值,则服务器可以自由地以任何顺序返回这些行,并且可以根据总体执行计划以不同的方式返回。换句话说,相对于无序列,这些行的排序顺序是不确定的。
LIMIT 和 ORDER BY 联合使用时的行为
If you combine LIMIT row_count with ORDER BY, MySQL stops sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast. If a filesort must be done, all rows that match the query without the LIMIT clause are selected, and most or all of them are sorted, before the first row_count are found. After the initial rows have been found, MySQL does not sort any remainder of the result set.
- 如果你联合使用 LIMIT 和 ORDER BY ,MySQL 会找到所需要的行后尽可能快的返回,而不是对所有满足查询条件的行进行排序。如果使用索引排序,那么速度会非常快;如果使用文件排序,所有满足条件都会被选中(不包括 Limit 条件),这些行的大多数,或全部都会被排序直到满足 Limit 的行数。满足的行数一旦找到,则不会对剩余的数据进行排序。
- 我们看一下官网的例子:
// 全表排序时
mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+----+----------+--------+// 部分排序时
mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 4 | 2 | 3.5 |
| 3 | 2 | 3.7 |
| 6 | 2 | 3.5 |
+----+----------+--------+// 可以看到 MySQL 并没有对所有数据整体排序之后再取数据
ORDER BY 或 GROUP BY 和 LIMIT 联合使用优化器默认使用有序索引
For a query with an ORDER BY or GROUP BY and a LIMIT clause, the optimizer tries to choose an ordered index by default when it appears doing so would speed up query execution. Prior to MySQL 5.7.33, there was no way to override this behavior, even in cases where using some other optimization might be faster. Beginning with MySQL 5.7.33, it is possible to turn off this optimization by setting the optimizer_switch system variable's prefer_ordering_index flag to off.
- 简单来说,5.7.33 以前会默认会选择排序字段的索引,即使存在更快的查询计划;5.7.33 开始我们可以关闭这种优化行为。我们来看一下官网提供的例子:
mysql> CREATE TABLE t (-> id1 BIGINT NOT NULL,-> id2 BIGINT NOT NULL,-> c1 VARCHAR(50) NOT NULL,-> c2 VARCHAR(50) NOT NULL,-> PRIMARY KEY (id1),-> INDEX i (id2, c1)-> );// prefer_ordering_index 开启(默认开启)
mysql> SELECT @@optimizer_switch LIKE '%prefer_ordering_index=on%';
+------------------------------------------------------+
| @@optimizer_switch LIKE '%prefer_ordering_index=on%' |
+------------------------------------------------------+
| 1 |
+------------------------------------------------------+mysql> EXPLAIN SELECT c2 FROM t-> WHERE id2 > 3-> ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: tpartitions: NULLtype: index
possible_keys: ikey: PRIMARYkey_len: 8ref: NULLrows: 2filtered: 70.00Extra: Using where// prefer_ordering_index 关闭
mysql> SET optimizer_switch = "prefer_ordering_index=off";
mysql> EXPLAIN SELECT c2 FROM t-> WHERE id2 > 3-> ORDER BY id1 ASC LIMIT 2\G
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: tpartitions: NULLtype: range
possible_keys: ikey: ikey_len: 8ref: NULLrows: 14filtered: 100.00Extra: Using index condition; Using filesort
如何解决
- 从上面我们可以知道,ORDER 列存在相同字段返回的顺序是不确定,且 LIMIT 和 ORDER BY 联合使用时可能不会对所有行进行排序,我们可以在排序字段中加入一个不存在重复值的列进行辅助排序,那么则不会存在这个问题。
- 比如在文章开头的案例中我们可以加入 ID 字段进行辅助排序:
SELECT * from test_1 ORDER BY create_date,id;
SELECT * from test_1 ORDER BY create_date,id LIMIT 0,2;
SELECT * from test_1 ORDER BY create_date,id LIMIT 8,2;
- 可以看到,分页的顺序和我们整体排序的顺序一致,不会出现分页错乱的问题。
其它说明
- MySQL 版本:
SELECT VERSION();5.7.36-log
个人简介
👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.
🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。
🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。
💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。
🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。
📖 保持关注我的博客,让我们共同追求技术卓越。
相关文章:

MySQL 系列:注意 ORDER 和 LIMIT 联合使用的陷阱
文章目录 前言背后的原因ORDER BY 排序列存在相同值时返回顺序是不固定的LIMIT 和 ORDER BY 联合使用时的行为ORDER BY 或 GROUP BY 和 LIMIT 联合使用优化器默认使用有序索引 如何解决其它说明个人简介 前言 不知道大家在在分页查询中有没有遇到过这个问题,分页查…...

通过实例理解OAuth2授权
在之前的《通过实例理解Go Web身份认证的几种方式[1]》和《通过实例理解Web应用授权的几种方式[2]》两篇文章中,我们对Web应用身份认证(AuthN)和授权(AuthZ)的几种方式做了介绍并配以实例增强理解。 在现实世界中,还有一大类的认证与授权是在前面的文章中…...

MATLAB2022安装下载教程
安装包需从夸克网盘自取: 链接:https://pan.quark.cn/s/373ffc9213a1 提取码:N7PW 1.将安装包解压 2.以管理员的身份运行文件夹中的setup文件 3.点击高级选项--->我有文件安装密钥 4. 选择【是】,进入下一步 5.输入密钥 0532…...
从零开始搭建Go语言开发环境
https://www.liwenzhou.com/posts/Go/install_go_dev/ “go 命令现在默认在模块感知模式下构建包,即使没有 go.mod 存在也是如此。 “您可以将 GO111MODULE 设置为 auto,仅当当前目录或任何父目录中存在 go.mod 文件时,才能启用模块感知模式…...

vite+vue3+ts+tsx+ant-design-vue项目框架搭建
参与公司项目开发一段时间了,项目用到了很多新的技术(vite,vue3,ts等等),但是框架都是别人搭好的,然后就想说如果是自己的话,会从零搭建一个吗,于是就有了这篇文章。 目录 一、涉及到的相关依…...

【5G PHY】5G小区类型、小区组和小区节点的概念介绍
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…...

创建个人网站(一)从零开始配置环境,搭建项目
目录 前言配置环境前端后端遇到的问题1.安装了nvm和node,vscode没反应2.安装完脚手架之后vue指令不存在 vscode插件(以后遇到好的会添进去) 前言 从刚开始学前端的html直到现在前后端都有在开发,我一直都有一个想法,就…...
fripside - promise lrc
[ti:promise] [ed:2] [rt:20] [ml:0|0] [00:05.172]words:Satoshi Yaginuma, Shinichiro Yamashita [00:09.664]music&arrangement:Satoshi Yaginuma, Shigetoshi Yamada [00:14.565]PCゲーム「ENGAGE LINKS」 (Alcot) エンディングテーマ [00:20.000] [00:46.442]朝の陽射…...
网络连接和协议
网络连接是通过一系列协议来实现的,其中TCP/IP协议和HTTP协议是其中两个关键的协议。 1. **TCP/IP协议:** - TCP/IP(Transmission Control Protocol/Internet Protocol)是一组用于在互联网上传输数据的协议。它是一个层次化的…...

MySQL数据库,表的增量备份与恢复
1. 从物理与逻辑的角度 数据库备份可以分为物理备份和逻辑备份。物理备份是对数据库操作系统的物理文件(如数据 文件,日志文件等)的备份。这种类型的备份适用于在出现问题时需要快速恢复的大型重要数据库。 物理备份又可以分为冷备份…...

13.Spring 整合 Kafka + 发送系统通知 + 显示系统通知
目录 1.Spring 整合 Kafka 2.发送系统通知 2.1 封装事件对象 2.2 开发事件的生产者和消费者 2.3 触发事件:在评论、点赞、关注后通知编辑 3.显示系统通知 3.1 通知列表 3.1.1 数据访问层 3.1.2 业务层 3.1.3 表现层 3.2 开发通知详情 3.2.1 开发数据…...

windows 服务器 怎么部署python 程序
一、要在 Windows 服务器上部署 Python 程序,您需要遵循以下步骤: 安装 Python:首先,在 Windows 服务器上安装 Python。您可以从官方网站(https://www.python.org/downloads/windows/)下载最新的 Python 安…...
Chapter 7 - 2. Congestion Management in Ethernet Storage Networks以太网存储网络的拥塞管理
Location of Ingress No-Drop Queues入口无损队列的位置 Ingress queues for no-drop traffic are maintained by all the ports in a lossless Ethernet network. For the sake of simplicity, Figure 7-1 shows ingress no-drop queue(s) only at one location, but in real…...
深入理解前端项目中的 package.json
在前端开发中,package.json 是一个很重要的文件,它在Node.js和前端项目中扮演着重要的角色。这个文件用于存储项目的元数据以及管理项目的依赖关系。 package.json 文件是每个Node.js项目和许多前端项目的核心。它不仅定义了项目的基本属性,…...
4-Docker命令之docker build
1.docker build介绍 docker build命令是用来使用Dockerfile文件创建镜像 2.docker build用法 docker build [参数] PATH | URL | - [root@centos79 ~]# docker build --helpUsage: docker buildx build [OPTIONS] PATH | URL | -Start a buildAliases:docker buildx build…...

Hdfs java API
1.在主机上启动hadoop sbin/start-all.sh 这里有一个小窍门,可以在本机上打开8088端口查看三台机器的连接状态,以及可以打开50070端口,查看hdfs文件状况。以我的主虚拟机为例,ip地址为192.168.198.200,所以可以采用下…...

大数据Doris(三十七):索引和Rollup基本概念和案例演示
文章目录 索引和Rollup基本概念和案例演示 一、基本概念 二、 案例演示...

2019年第八届数学建模国际赛小美赛B题数据中心冷出风口的设计解题全过程文档及程序
2019年第八届数学建模国际赛小美赛 B题 数据中心冷出风口的设计 原题再现: 这是数据中心空调设计面临的一个问题。在一些数据中心,计算机机柜是开放的,在一个房间里排列成三到四排。冷却后的空气通过主管进入房间,并分为三到四个…...

mmpose 使用笔记
目录 自己整理的可以跑通的代码: 图片demo: 检测加关键点 自己整理的可以跑通的代码: 最强姿态模型 mmpose 使用实例-CSDN博客 图片demo: python demo/image_demo.py \tests/data/coco/000000000785.jpg \configs/body_2d_k…...

<url-pattern>/</url-pattern>与<url-pattern>/*</url-pattern>的区别
<url-pattern>/</url-pattern> servlet的url-pattern设置为/时, 它仅替换servlet容器的默认内置servlet,用于处理所有与其他注册的servlet不匹配的请求。直白点说就是,所有静态资源(js,css,ima…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

并发编程 - go版
1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...