MYSQL JOIN ON 中的相关子查询 迁移 tidb 8.5 怎么改

迁衡基于规则 my.subquery.join_on_correlated 分析 MYSQL JOIN ON 中的相关子查询 到 tidb 8.5 的兼容性、改写路径与验证建议。

兼容性判定

公开资料依据 · 建议 PoC 复核
支持度none
严重度critical
置信度low
依据规则my.subquery.join_on_correlated

怎么改

先保留子查询在 ON 的原布尔位置;仅已证明为顶层合取且 join 类型/相关侧不改变外行保留的 EXISTS/IN/NOT EXISTS 可改半连接/反连接,OR/NOT/CASE 等组合须物化 true/false/unknown 真值标记并在原布尔位置替换;外连接顶层合取也必须在 ON 内承接,不得预过滤保留侧,且不得移到 WHERE;NOT IN 用 NULL-aware 结果承接 NULL;ANY/ALL 保留空集/三值逻辑;聚合 scalar 要按基数分支:无 GROUP BY 的纯聚合仅在未被 HAVING/LIMIT/OFFSET/集合操作消除时才恰好一行,此时 COUNT 空集=0、其他多数聚合=NULL,按相关键预计算后用 LEFT JOIN/真值标记保留外行并补回默认值。标量基数必须在全部查询块算子之后判定 0/1/多行:零行=>NULL、多行=>报错;GROUP BY/HAVING 及 LIMIT/OFFSET/集合操作不得用普通内连接丢行或 DISTINCT/LIMIT 1 偷压;非聚合 scalar 仅在唯一约束证明至多一行时改写并保留零行 NULL/多行报错;嵌套层逐层暴露并传递相关键,禁止删除子查询或静默去重

判定说明

TiDB 8.5 文档与 v8.5.7 planner 拒绝 JOIN ON 中任意子查询;本 feature 仅覆盖静态可证明相关的子集,未命中不代表支持;建议 PoC 复核精确补丁版本和改写基数

库侧 / 应用侧路径

库侧改造

可行:逐层暴露相关键,用 CTE/派生关系或临时表预计算键与聚合结果,再以显式 JOIN 接回并固定一对一/一对多基数

应用侧改造

可行:查询构建层拆为参数化的预查询与主查询;需要同一快照时保持单事务并限制中间结果规模

推荐路线:db_side。验证建议:覆盖相关键 NULL、无匹配、重复内行、scalar 零/一/多行、内连接顶层合取及 OR/NOT/CASE 中的 EXISTS 真值与 UNKNOWN;另测外连接顶层合取不得预过滤保留侧及空扩展,覆盖嵌套层、影响行数与计划,并用目标精确版本复核 ERROR 1105

规则样例

SELECT a.id FROM t_join_exists a JOIN t_join_exists b ON EXISTS (SELECT 1 FROM t_join_exists c WHERE c.id = a.id)
SELECT a.id FROM t_join_scalar a JOIN t_join_scalar b ON b.v = (SELECT MAX(c.v) FROM t_join_scalar c WHERE c.id >= a.id)
SELECT a.id FROM t_join_exists a JOIN t_join_exists b ON EXISTS (SELECT 1 FROM t_join_exists c WHERE c.id = 1)

参考来源

相关改造点

社群/联系

迁移卡住时,带着案例找人复核

迁移路上遇到具体问题?微信群、1v1 咨询与邮箱,随时找得到人。

微信交流群 微信二维码

扫码添加微信,邀您加入交流群;亦可搜索微信号 prejudice_me。

邮箱咨询

m01dm01db01@foxmail.com

发源库、目标库、代码规模和已脱敏案例短链,便于估算改造工作量。