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

 更新时间:2021年07月31日 10:49:39   作者:simpleapples  
ORDER BY 语句用于根据指定的列对结果集进行排序,在日常工作中经常会用到,这篇文章主要给大家介绍了关于MySQL子查询中order by不生效问题的解决方法,需要的朋友可以参考下

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

问题描述

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

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

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操作,进而查询出的商品的最新修改时间。


在区域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 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分区表的局限和限制详解

    本文对Mysql分区表的局限性做了一些总结,因为个人能力以及测试环境的 原因,有可能有错误的地方,还请大家看到能及时指出,当然有兴趣的朋友可以去官方网站查阅。
    2017-03-03
  • MySQL与PHP的基础与应用专题之索引

    MySQL与PHP的基础与应用专题之索引

    MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,本系列将带你掌握php与mysql的基础应用,本篇从索引开始
    2022-02-02
  • MySQL优化全攻略-相关数据库命令

    MySQL优化全攻略-相关数据库命令

    MySQL优化全攻略-相关数据库命令...
    2006-11-11
  • MySQL-MMM安装指南(Multi-Master Replication Manager for MySQL)

    MySQL-MMM安装指南(Multi-Master Replication Manager for MySQL)

    这篇文章主要介绍了mysql Multi-Master Replication Manager for MySQL的安装方法,需要的朋友可以参考下
    2014-02-02
  • MySQL 5.6 中 TIMESTAMP 的变化分析

    MySQL 5.6 中 TIMESTAMP 的变化分析

    这篇文章主要介绍了MySQL 5.6 中 TIMESTAMP 的变化分析,需要的朋友可以参考下
    2015-08-08
  • MySQL连接查询你真的学会了吗?

    MySQL连接查询你真的学会了吗?

    日常使用数据库查询语句时,单表查询尝尝不能满足项目的业务需求,在项目开发过程中,有很多需求都是要涉及到多表的连接查询,这篇文章主要给大家介绍了关于MySQL连接查询的相关资料,需要的朋友可以参考下
    2021-06-06
  • MySQL修改root账号密码的方法

    MySQL修改root账号密码的方法

    这篇文章介绍了两种情况,知道root密码的情况下修改root密码,以及忘记了root密码,如何对root的密码进行修改,需要的朋友可以参考下
    2015-07-07
  • MySQL优化之InnoDB优化

    MySQL优化之InnoDB优化

    InnoDB是为Mysql处理巨大数据量时的最大性能设计。它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。在数据量大的网站或是应用中Innodb是倍受青睐的。那么它就不需要优化了吗,答案很显然:当然不是!!!
    2017-03-03
  • MySQL字符编码设置方法

    MySQL字符编码设置方法

    这篇文章主要介绍了MySQL字符编码设置方法的相关资料,需要的朋友可以参考下
    2016-05-05
  • mysql 8.0.27 安装配置方法图文教程(Windows64位)

    mysql 8.0.27 安装配置方法图文教程(Windows64位)

    这篇文章主要为大家详细介绍了mysql 8.0.27 下载、安装与配置图文教程,文中安装步骤介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04

最新评论