一. 前言
调整表的Join顺序是join操作性能优化的一个常见手段。一般SQL计算引擎都支持在Join计算的时候都能自动根据代价将小表调整到join的右侧,大表调整到join的左侧来进行计算从而获得良好的性能。本文通过走读代码来探索在Presto中是如何实现根据代价调整join计算时候的表顺序的。
二. 调整join的表顺序代码走读
调整表的join顺序是在ReorderJoins优化器实现的,其实现步骤为:
joinEnumerator.chooseJoinOrder
createJoinAccordingToPartitioning
createJoin
setJoinNodeProperties
getPossibleJoinNodes //此处会根据join的类型生成各种组合的Join操作子树,比如 A join B 会生成 A partitioned join B, A broadcast join B,B partitioned join A, B broadcast join A 4种组合
resultComparator.min(possibleJoinNodes) // 根据代价计算公式从上述所有组合中选择代价最小的执行计划执行。小表join大表的代价 大于 大表 join 小表的代价,因此优化后选择了大表 join 小表的计划执行树执行,从而实现join顺序调整优化
三. 代价计算方式
在Presto中,一个PlanNode的代价主要与CPUCost,memoryCost, networkCost有关,默认的计算公式为:
Cost = getCpuCost() * cpuWeight + getMaxMemory() * memoryWeight + getNetworkCost() * networkWeight;
其中,CPU,Memory,NetWork的默认权重分别为:75%,10%, 15%。