MySQL子查询中order by不生效问题的解决方法


Posted in MySQL onAugust 02, 2021

一个偶然的机会,发现一条SQL语句在不同的MySQL实例上执行得到了不同的结果。

问题描述

创建商品表product_tbl和商品操作记录表product_operation_tbl两个表,来模拟下业务场景,结构和数据如下:

MySQL子查询中order by不生效问题的解决方法

MySQL子查询中order by不生效问题的解决方法

接下来需要查询所有商品最新的修改时间,使用如下语句:

select t1.id, t1.name, t2.product_id, t2.created_at  from product_tbl t1 left join (select * from product_operation_log_tbl order by created_at desc) t2 on t1.id = t2.product_id group by t1.id;

通过结果可以看到,子查询先将product_operation_log_tbl里的所有记录按创建时间(created_at)逆序,然后和product_tbl进行join操作,进而查询出的商品的最新修改时间。

MySQL子查询中order by不生效问题的解决方法

在区域A的MySQL实例上,查询商品最新修改时间可以得到正确结果,但是在区域B的MySQL实例上,得到的修改时间并不是最新的,而是最老的。通过对语句进行简化,发现是子查询中的order by created_at desc语句在区域B的实例上没有生效。

排查过程

难道区域会影响MySQL的行为?经过DBA排查,区域A的MySQL是5.6版,区域B的MySQL是5.7版,并且找到了这篇文章:

https://blog.csdn.net/weixin_42121058/article/details/113588551

根据文章的描述,MySQL 5.7版会忽略掉子查询中的order by语句,可令人疑惑的是,我们模拟业务场景的MySQL是8.0版,并没有出现这个问题。使用docker分别启动MySQL 5.6、5.7、8.0三个实例,来重复上面的操作,结果如下:

MySQL子查询中order by不生效问题的解决方法

可以看到,只有MySQL 5.7版忽略了子查询中的order by。有没有可能是5.7引入了bug,后续版本又修复了呢?

问题根因

继续搜索文档和资料,发现官方论坛中有这样一段描述:

A "table" (and subquery in the FROM clause too) is - according to the SQL standard - an unordered set of rows. Rows in a table (or in a subquery in the FROM clause) do not come in any specific order. That's why the optimizer can ignore the ORDER BY clause that you have specified. In fact, SQL standard does not even allow the ORDER BY clause to appear in this subquery (we allow it, because ORDER BY ... LIMIT ... changes the result, the set of rows, not only their order). You need to treat the subquery in the FROM clause, as a set of rows in some unspecified and undefined order, and put the ORDER BY on the top-level SELECT.

问题的原因清晰了,原来SQL标准中,table的定义是一个未排序的数据集合,而一个SQL子查询是一个临时的table,根据这个定义,子查询中的order by会被忽略。同时,官方回复也给出了解决方案:将子查询的order by移动到最外层的select语句中。

总结

在SQL标准中,子查询中的order by是不生效的

MySQL 5.7由于在这个点上遵循了SQL标准导致问题暴露,而在MySQL 5.6/8.0中这种写法依然是生效的

到此这篇关于MySQL子查询中order by不生效问题的文章就介绍到这了,更多相关MySQL子查询order by不生效内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

参考文档

https://stackoverflow.com/questions/26372511/mysql-mariadb-order-by-inside-subquery

https://mariadb.com/kb/en/why-is-order-by-in-a-from-subquery-ignored/

 

MySQL 相关文章推荐
新手必备之MySQL msi版本下载安装图文详细教程
May 21 MySQL
MySQL 发生同步延迟时Seconds_Behind_Master还为0的原因
Jun 21 MySQL
浅谈MySQL函数
Oct 05 MySQL
MySQL分区表实现按月份归类
Nov 01 MySQL
MySQL利用UNION连接2个查询排序失效详解
Nov 20 MySQL
MySQL中int (10) 和 int (11) 的区别
Jan 22 MySQL
一条慢SQL语句引发的改造之路
Mar 16 MySQL
Mysql如何实现不存在则插入,存在则更新
Mar 25 MySQL
Nebula Graph解决风控业务实践
Mar 31 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
Jun 14 MySQL
一文解答什么是MySQL的回表
Aug 05 MySQL
MySQL中utf8mb4排序规则示例
Aug 02 #MySQL
MySql子查询IN的执行和优化的实现
MySQL里面的子查询的基本使用
Aug 02 #MySQL
Centos7中MySQL数据库使用mysqldump进行每日自动备份的编写
Aug 02 #MySQL
为什么MySQL选择Repeatable Read作为默认隔离级别
使用ORM新增数据在Mysql中的操作步骤
Jul 26 #MySQL
mysql脏页是什么
Jul 26 #MySQL
You might like
如何在PHP中使用正则表达式进行查找替换
2013/06/13 PHP
一个不易被发现的PHP后门代码解析
2014/07/05 PHP
PHP中static关键字以及与self关键字的区别
2015/07/01 PHP
PHP实现简单的模板引擎功能示例
2017/09/02 PHP
php生成微信红包数组的方法
2019/09/05 PHP
将form表单中的元素转换成对象的方法适用表单提交
2014/05/02 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
jQuery中before()方法用法实例
2014/12/25 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
深入学习JavaScript对象
2015/10/13 Javascript
JavaScript如何获取数组最大值和最小值
2015/11/18 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
2015/11/29 Javascript
AngularJS下对数组的对比分析
2016/08/24 Javascript
webpack实现热加载自动刷新的方法
2017/07/30 Javascript
浅谈Emergence.js 检测元素可见性的 js 插件
2017/11/18 Javascript
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
JS拖拽排序插件Sortable.js用法实例分析
2019/02/20 Javascript
[03:08]迎霜节狂欢!2018年迎霜节珍藏Ⅰ一览
2018/12/25 DOTA
[01:19:46]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
[01:07:19]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第一场 1月19日
2021/03/11 DOTA
pandas DataFrame实现几列数据合并成为新的一列方法
2018/06/08 Python
Python实现的简单读写csv文件操作示例
2018/07/12 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
Python学习笔记之函数的参数和返回值的使用
2019/11/20 Python
JPA的特点
2014/10/25 面试题
实习单位接收函
2014/01/11 职场文书
新学期决心书
2014/03/11 职场文书
公司年会主持词
2014/03/22 职场文书
团日活动总结书
2014/05/08 职场文书
小学运动会报道稿
2014/10/04 职场文书
寝室长工作失责检讨书
2014/10/06 职场文书
2014年精神文明建设工作总结
2014/11/19 职场文书
停课通知书
2015/04/24 职场文书
检讨书格式
2019/04/25 职场文书
详解python的异常捕获
2022/03/03 Python
Mysql InnoDB 的内存逻辑架构
2022/05/06 MySQL