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入门命令之函数-单行函数-流程控制函数
Apr 05 MySQL
mysql的MVCC多版本并发控制的实现
Apr 14 MySQL
Mysql MVCC机制原理详解
Apr 20 MySQL
详解MySQL主从复制及读写分离
May 07 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
Mysql数据库中datetime、bigint、timestamp来表示时间选择,谁来存储时间效率最高
Aug 23 MySQL
MySQL悲观锁与乐观锁的实现方案
Nov 02 MySQL
Nebula Graph解决风控业务实践
Mar 31 MySQL
MySQL数据库事务的四大特性
Apr 20 MySQL
MySQL 字符集 character
May 04 MySQL
MySQL 语句执行顺序举例解析
Jun 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临时文件的安全性分析
2014/07/04 PHP
php写app接口并返回json数据的实例(分享)
2017/05/20 PHP
PHP 实现 JSON 数据的编码和解码操作详解
2020/04/22 PHP
Javascript 继承机制实例
2009/08/12 Javascript
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
js将json格式内容转换成对象的方法
2013/11/01 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
2014/03/03 Javascript
js数组的基本操作(很全自己整理的)
2014/10/16 Javascript
JS中三目运算符和if else的区别分析与示例
2014/11/21 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
jquery根据一个值来选中select下的option实例代码
2016/08/29 Javascript
详解Angular之constructor和ngOnInit差异及适用场景
2017/06/22 Javascript
js canvas实现橡皮擦效果
2018/12/20 Javascript
JavaScript禁止右击保存图片,禁止拖拽图片的实现代码
2020/04/28 Javascript
小程序实现图片移动缩放效果
2020/05/26 Javascript
小程序实现列表展开收起效果
2020/07/29 Javascript
vue 中this.$set 动态绑定数据的案例讲解
2021/01/29 Vue.js
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
安装dbus-python的简要教程
2015/05/05 Python
Python基于pygame模块播放MP3的方法示例
2017/09/30 Python
详解python中的Turtle函数库
2018/11/19 Python
python实现给scatter设置颜色渐变条colorbar的方法
2018/12/13 Python
详解用python写网络爬虫-爬取新浪微博评论
2019/05/10 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
Tensorflow训练模型越来越慢的2种解决方案
2020/02/07 Python
浅析Python打包时包含静态文件处理方法
2021/01/15 Python
HTML5+JS实现俄罗斯方块原理及具体步骤
2013/11/29 HTML / CSS
WEB控件可以激发服务端事件,请谈谈服务端事件是怎么发生并解释其原理?自动传回是什么?为什么要使用自动传回?
2012/02/21 面试题
最新的大学生找工作自我评价
2013/09/29 职场文书
学生打架检讨书大全
2014/01/23 职场文书
医学求职自荐信
2014/06/21 职场文书
机关干部三严三实心得体会
2014/10/13 职场文书
小学班主任事迹材料
2014/12/17 职场文书
大学生预备党员自我评价
2015/03/04 职场文书
2016年基层党组织公开承诺书
2016/03/25 职场文书
导游词之塘栖古镇
2019/12/04 职场文书