首先spark sql的设计总体上:1,首先我们要有一个树的节点,通过这个节点可以继承出单孩子节点,双孩子节点,叶子节点以及多孩子节点.
1.1,树的节点有最基本的遍历操作,这个遍历操作支持各种遍历,前缀后缀中缀,因为有些expression的折叠方式这样要求.
2,expression继承的是树的节点,因为expression可能含有两个孩子,一个孩子,多个孩子,也可能没有孩子.
3,QueryPlan继承的也是树节点,因为QueryPlan是可能还有如join两个孩子的逻辑算子,aggregation一个孩子的逻辑算子,或者relation叶子节点的逻辑算子.由QueryPlan再继承出LogicalPlan和PhysicalPlan的.LogicalPlan之上又有UnaryNode,BinaryNode,LeafNode,通过这些可以集成出join,aggregation等逻辑算子.PhysicalPlan在spark sql中叫SparkPlan,同理有SparkPlan继承出的UnaryNode,BinaryNode,LeafNode,通过这些可以继承出最终的物理join,aggregation.4,对于select upper(a) from T;执行计划为Project--Relation,Project中输入的是a的attribute,但是Relation中出来的是整行,project通过projection,利用eval计算,在projection构造的时候有一个绑定的reference 对于这个例子来说Relation出来的是整张表,在构造Projection的时候,确定banding信息,然后利用传入Project中的每个expression的eval计算出来.总之,每个expression在各个operator中计算之前都有一个banding操作,将所要计算的操作和输入的attribute对应起来.表达式应该和算子一样重要,每个算子都应该有计算表达式的能力.下面通过spark sql中表达式的计算讲解表达式.1,当SQL中含有aggregation时 T的schema为(a,b) a,当我们写如下语句:select sum(b) from T 生成的物理执行计划为Aggregation--Project--ExistingRDD,因为有ColumnPruning规则作用与此 b,当我们写如下语句:select a,sum(b) from T group by a 生成的物理执行计划为Aggregation--ExistingRDD,这里Aggregation传入的是一个expression的vector,这个expression的vector能够被计算 c,当我们这样写呢:select a+sum(b) from T group by a 生成的物理执行计划同样为Aggregation--ExistingRDD,只不过这里是传入的一个expression d,但是如果我们在一个表schema为(a,b,c)上这样:select c,sum(b) from T group by a,这个会出错,但是错误代码在哪里,有没有错误代码?2,当SQL中含有order by时 T的schema为(a,b,c) a,当我们写如下语句:select a from T order by a 生成的物理执行计划为:Sort--Project,这里的Project并不是存在ColumnPruning,而是sort语句是在select执行之后再执行3,当SQL中只有filter,或者只有select from时 T的schema(n,l) a,当我们写如下语句:select n,upper(l) from lowerCaseData where n > 1 生成的物理执行计划为:Project--Filter--Relation(ExistingRDD) b,但是当我们写了如下语句:select n,l from lowerCaseData where n > 1 生成的物理执行计划为:Filter-- Relation(ExistingRDD) a和b有何区别?首先,明显地a没有upper,但是,在生成AST,转换为逻辑执行计划的时候是有Project的,但是为何在最终物理执行计划中没有呢?查询优化废了它.是哪条查询优化规则将Project省略了? 这条规则在ColumnPruning中,因为逻辑计划中发现Project的输入和输出一样,所以这个Project可以去掉.如果说我们将b改为select l from lowerCaseData where n > 1,此时的物理执行计划就还是Project--Filter--Relation(ExistingRDD).但是如果将b改为select n from lowerCaseData where n > 1,这个时候spark生成的物理执行计划为Project--Filter--Relation(ExistingRDD),这里是不是有问题,因为filter的输入在此时只需要有属性n,到底是将filter放在project之上,还是将filter放到project之下呢?或者利用schema为(a,b,c)的表做实验,select a from T where a<3 and b <3这个SQL,其生成的还是Project--Filter--Relation(ExistingRDD),难道不应该是Project--Filter--Project--Relation(ExistingRDD).
来源: