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 相关文章推荐
多表查询、事务、DCL
Apr 05 MySQL
MySQL之DML语言
Apr 05 MySQL
MySQL数字类型自增的坑
May 07 MySQL
MySQL 分组查询的优化方法
May 12 MySQL
MySQL 时间类型的选择
Jun 05 MySQL
mysql联合索引的使用规则
Jun 23 MySQL
MySQL中order by的使用详情
Nov 17 MySQL
MySql数据库触发器使用教程
Jun 01 MySQL
MySQL数据库之存储过程 procedure
Jun 16 MySQL
MySQL详细讲解变量variables的用法
Jun 21 MySQL
mysql查看表结构的三种方法总结
Jul 07 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之APC缓存详细介绍 apc模块安装
2014/01/13 PHP
yii通过小物件生成view的方法
2016/10/08 PHP
PHP实现对数组分页处理实例详解
2017/02/07 PHP
jQuery 学习6 操纵元素显示效果的函数
2010/02/07 Javascript
JavaScript中获取鼠标位置相关属性总结
2014/10/11 Javascript
AngularJS入门教程(二):AngularJS模板
2014/12/06 Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
2015/03/04 Javascript
javascript中eval函数用法分析
2015/04/25 Javascript
js实现顶部可折叠的菜单工具栏效果实例
2015/05/09 Javascript
谈谈impress.js初步理解
2015/09/09 Javascript
详解JS面向对象编程
2016/01/24 Javascript
Javascript获取图片原始宽度和高度的方法详解
2016/09/20 Javascript
Vue.js在数组中插入重复数据的实现代码
2017/11/17 Javascript
JS学习笔记之数组去重实现方法小结
2019/05/29 Javascript
jQuery实时统计输入框字数及限制
2020/06/24 jQuery
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
python中pygame模块用法实例
2014/10/09 Python
python结合API实现即时天气信息
2016/01/19 Python
Python实现二叉堆
2016/02/03 Python
Python入门之三角函数tan()函数实例详解
2017/11/08 Python
Python3数据库操作包pymysql的操作方法
2018/07/16 Python
python3实现zabbix告警推送钉钉的示例
2019/02/20 Python
opencv之为图像添加边界的方法示例
2019/12/26 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
伦敦一家非常流行的时尚精品店:Oxygen Boutique
2017/01/15 全球购物
优秀大学生的自我评价
2014/01/16 职场文书
红领巾心向党广播稿
2014/01/19 职场文书
转让协议书范本
2014/04/15 职场文书
小学生操行评语
2014/04/22 职场文书
节水标语大全
2014/06/11 职场文书
2014各大专业毕业生自我评价
2014/09/17 职场文书
法人代表证明书格式
2014/10/01 职场文书
公民授权委托书
2014/10/15 职场文书
挂职锻炼工作总结2015
2015/05/28 职场文书
python 使用pandas读取csv文件的方法
2022/12/24 Python