热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

不在PrestovsSparkSQL的实现中

如何解决《不在PrestovsSparkSQL的实现中》经验,为你挑选了1个好方法。

我得到了一个非常简单的查询,当在同一硬件上运行Spark SQL和Presto时(3小时vs 3分钟),显示出显着的性能差异。

SELECT field 
FROM test1 
WHERE field NOT IN (SELECT field FROM test2)

经过对查询计划的研究,我发现原因是Spark SQL如何处理NOT IN谓词子查询。为了正确处理NOT IN的NULL,Spark SQL将NOT IN谓词转换为Left AntiJoin( (test1=test2) OR isNULL(test1=test2))

Spark SQL引入OR isNULL(test1=test2)了确保的正确语义NOT IN

但是,ORLeft AntiJoin连接谓词的唯一可行的物理连接策略Left AntiJoinBroadcastNestedLoopJoin。在当前阶段,我可以将NOT IN改写为NOT EXISTS来解决此问题。在NOT EXISTS的查询计划中,我可以看到join谓词是Left AntiJoin(test1=test2)为NOT EXISTS(5分钟完成)导致更好的物理联接运算符的原因。

到目前为止,我很幸运,因为我的数据集当前没有任何NULL属性,但是将来可能会具有,而NOT IN的语义正是我真正想要的。

所以我检查了Presto的查询计划,它没有真正提供,Left AntiJoinSemiJoin与一起使用FilterPredicate = not (expr)。Presto的查询计划没有提供太多信息,例如Spark。

所以我的问题更像是:

我可以假设Presto有更好的物理联接运算符来处理NOT IN操作吗?与Spark SQL不同,它不依赖于连接谓词的重写isnull(op1 = op2)来确保逻辑计划级别中NOT IN的正确语义。



1> Piotr Findei..:

我实际上是在Presto中实施NULL半联接(IN谓词)处理的人。

Presto除了使用散列分区¹外,还使用“复制空值和任何行”复制模式,这使它可以INNULLs的任一侧都存在s 的情况下正确处理IN,而不会退回到广播,或者使执行成为单线程或单线程-节点。运行时性能成本实际上与NULL根本不存在值的情况相同。

如果您想了解有关Presto内部的更多信息,请加入Presto Community Slack#dev上的频道。

¹)确切地说,半连接是基于哈希的分区或广播,具体取决于基于成本的决策或配置。


推荐阅读
author-avatar
imba-Y_685
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有