问题背景
在 TiDB v8.5.2 版本升级后,有用户反馈老版本带子查询的时候结果是顺序的,但是新版本开始结果不对。
问题原因
问题的根本原因其实是子查询的排序操作未被有效执行,这是新版本 tidb 为了兼容 sql 标准行为设置。可以认为是新老版本行为差异。这可以通过调整 TiDB 的 tidb_remove_orderby_in_subquery
配置参数来改进。
tidb_remove_orderby_in_subquery
从 v6.1.0 版本开始引入
在 v7.2.0 之前版本中为 OFF,在 v7.2.0 及之后版本中为 ON。
官网相关说明:https://docs.pingcap.com/zh/tidb/stable/system-variables/#tidb_remove_orderby_in_subquery-%E4%BB%8E-v610-%E7%89%88%E6%9C%AC%E5%BC%80%E5%A7%8B%E5%BC%95%E5%85%A5
MySQL
诊断步骤
-
创建一个测试表:
create table cb_limit (id bigint(20), name varchar(20), age int); insert into cb_limit values (1, 'a', 1); insert into cb_limit values (2, 'b', 2); insert into cb_limit values (3, 'c', null); insert into cb_limit values (4, 'd', null);
-
执行以下 SQL 查询并验证结果是否正确:
select * from (select age from cb_limit order by age desc) x limit 1;
-
如果查询结果不为期望值(例如,返回
1
而不是2
),则可以确定是此问题。
解决方案是修改 TiDB 配置参数 tidb_remove_orderby_in_subquery
的值以适当处理子查询中的 ORDER BY 行为。推荐在 sql 最外层再加一遍 order by。
影响版本 v7.2.0 版本以后