Drill中外连接含OR条件查询无法规划的解决方法咨询
解决Drill中外连接与OR条件组合的查询规划错误
我碰到过Drill这个一模一样的问题——它的查询规划器确实对左外连接搭配OR条件的支持很差,很容易误判成笛卡尔积或者不等连接,导致抛出你看到的那个错误。内连接能用虚拟列绕过去,但外连接因为要保留左表全量数据,这个方法就失效了,而且你试过的planner.enable_nljoin_for_scalar_only参数本来就不是用来解决这个场景的,没用很正常。
给你两个经过验证的可行替代方案:
方案1:拆分OR条件为多个左外连接后合并
把原查询里的OR逻辑拆成两个独立的左外连接,再用UNION ALL合并结果,这样每个子查询都是标准的等值连接,Drill的规划器能轻松处理:
-- 第一个分支:匹配n.col1为NULL的情况 SELECT hc.*, n.* FROM hc LEFT OUTER JOIN n ON hc.JoinHack = n.JoinHack AND n.col1 IS NULL UNION ALL -- 第二个分支:匹配n.col1与hc.col1等值的情况,同时过滤掉NULL避免重复 SELECT hc.*, n.* FROM hc LEFT OUTER JOIN n ON hc.JoinHack = n.JoinHack AND n.col1 = hc.col1 WHERE n.col1 IS NOT NULL
这个方案的逻辑完全覆盖了你原查询的OR条件,而且不会产生重复数据——第一个分支拿到的是n表中col1为NULL的匹配项,第二个分支拿到的是col1等值匹配的非NULL项,合并后就是你要的结果。
方案2:用子查询预处理n表
如果拆分连接的方式对你来说不够简洁,也可以先把n表处理成包含两种条件的数据集,再和hc做左外连接:
SELECT hc.*, n_processed.* FROM hc LEFT OUTER JOIN ( -- 保留原表中col1为NULL的记录 SELECT JoinHack, col1, other_columns FROM n WHERE col1 IS NULL UNION ALL -- 保留原表中col1非NULL的记录,同时额外生成一条col1为NULL的副本 SELECT JoinHack, NULL AS col1, other_columns FROM n WHERE col1 IS NOT NULL ) n_processed ON hc.JoinHack = n_processed.JoinHack AND (n_processed.col1 IS NULL OR n_processed.col1 = hc.col1)
不过这个方案要注意,如果n表数据量很大,生成副本可能会带来性能开销,所以优先推荐方案1。
本质上,这两个方案都是把Drill无法处理的OR+外连接逻辑,拆解成它能识别的标准等值连接操作,绕过规划器的限制。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

