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 22 MySQL
正确使用MySQL INSERT INTO语句
May 26 MySQL
MySQL中in和exists区别详解
Jun 03 MySQL
MySQL索引失效的典型案例
Jun 05 MySQL
mysql 如何获取两个集合的交集/差集/并集
Jun 08 MySQL
如何使用分区处理MySQL的亿级数据优化
Jun 18 MySQL
关于mysql中时间日期类型和字符串类型的选择
Nov 27 MySQL
MySQL图形化管理工具Navicat安装步骤
Dec 04 MySQL
一文搞清楚MySQL count(*)、count(1)、count(col)区别
Mar 03 MySQL
实战 快速定位MySQL的慢SQL
Mar 22 MySQL
MySql中的json_extract函数处理json字段详情
Jun 05 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 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
探讨fckeditor在Php中的配置详解
2013/06/08 PHP
一个非常实用的php文件上传类
2017/07/04 PHP
PHP实现重载的常用方法实例详解
2017/10/18 PHP
微信分享的标题、缩略图、连接及描述设置方法
2014/10/14 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
实例解析JS布尔对象的toString()方法和valueOf()方法
2015/10/25 Javascript
跟我学习javascript的函数和函数表达式
2015/11/16 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
2016/10/05 Javascript
BootStrap网页中代码显示用法详解
2016/10/21 Javascript
js实现兼容PC端和移动端滑块拖动选择数字效果
2017/02/16 Javascript
js实现简单的选项卡效果
2017/02/23 Javascript
详解webpack引入第三方库的方式以及注意事项
2019/01/15 Javascript
微信小程序学习笔记之文件上传、下载操作图文详解
2019/03/29 Javascript
微信小程序实现的一键复制功能示例
2019/04/24 Javascript
Vue仿微信app页面跳转动画效果
2019/08/21 Javascript
ES10的13个新特性示例(小结)
2019/09/23 Javascript
[58:23]LGD vs TNC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/16 DOTA
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)
2016/09/21 Python
基于并发服务器几种实现方法(总结)
2017/12/29 Python
Python生成任意范围任意精度的随机数方法
2018/04/09 Python
10招!看骨灰级Pythoner玩转Python的方法
2019/04/15 Python
Python数据可视化 pyecharts实现各种统计图表过程详解
2019/08/15 Python
python 3.74 运行import numpy as np 报错lib\site-packages\numpy\__init__.py
2019/10/06 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
美的官方商城:Midea
2016/09/14 全球购物
美国生鲜及杂货电商:FreshDirect
2018/01/29 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
LINUX下线程,GDI类的解释
2016/12/14 面试题
实习生个人找工作的自我评价
2013/10/30 职场文书
乌镇导游词
2015/02/02 职场文书
常务副总经理岗位职责
2015/02/02 职场文书
2015年中秋节主持词
2015/07/30 职场文书
2015年成本会计工作总结
2015/10/14 职场文书
游戏《我的世界》澄清Xbox版暂无计划加入光追
2022/04/03 其他游戏
深入理解 Golang 的字符串
2022/05/04 Golang