MySQL 5.5迁移至MariaDB 10.0后子查询排序失效问题求助
关于MySQL 5.5转MariaDB 10.0后子查询排序失效的问题
这个问题其实涉及到SQL标准的规定,以及两款数据库在子查询排序处理上的实现差异,咱们来详细拆解清楚:
核心原因:SQL标准对派生表排序的要求
首先要明确一个关键规则:当ORDER BY出现在FROM子句的派生表(也就是你例子里的子查询)中时,除非搭配LIMIT子句,否则数据库有权忽略这个排序指令。
这是因为派生表本质上是一个临时数据集,SQL标准并不要求数据库保留子查询内部的排序结果——数据库会根据查询优化的需要,自行决定是否执行这个排序,毕竟无序的数据集在后续处理中可能更高效。
MySQL 5.5和MariaDB 10.0的差异
- MySQL 5.5的特殊行为:早期的MySQL并没有严格遵循这个标准,它会“额外”保留派生表中
ORDER BY的结果,哪怕没有LIMIT。这就导致你的第二个语句在MySQL 5.5里看起来生效了,但这其实是一个非标准的实现。 - MariaDB 10.0的标准处理:MariaDB在这个版本里更严格地对齐了SQL标准,所以直接忽略了派生表中没有搭配
LIMIT的ORDER BY,结果自然回到了默认的升序(通常是表的物理存储顺序或主键的默认排序)。
补充:你的语句里还有个小错误
你第二个语句的子查询里写了ORDER BY tmpTable.id DESC,但tmpTable是外层派生表的别名,子查询内部应该用原表的列名,比如ORDER BY id DESC。不过这个错误不是排序失效的核心原因,哪怕改对了,在MariaDB 10.0里还是不会生效,因为没有LIMIT。
正确的写法
不管用MySQL还是MariaDB,想要保证最终结果的排序,都应该把ORDER BY放在最外层查询,也就是你第一个语句的写法:
select * from ( select * from MYTABLE ) tmpTable ORDER BY tmpTable.id DESC
如果确实需要在子查询里先排序再做后续处理(比如分页场景),必须给子查询加上LIMIT,强制数据库执行排序:
select * from ( select * from MYTABLE ORDER BY id DESC LIMIT 18446744073709551615 ) tmpTable
(这里用了MySQL/MariaDB支持的最大整数作为LIMIT值,相当于获取所有行同时保留排序)
内容的提问来源于stack exchange,提问作者MathAng
相关产品推荐
相关产品推荐

