快捷搜索:

您的位置:环球彩票登陆 > 环球彩票登陆 > 斯Parker SQL Catalyst优化器环球彩票登陆

斯Parker SQL Catalyst优化器环球彩票登陆

发布时间:2019-11-03 15:38编辑:环球彩票登陆浏览(167)

    比如我们由这样一条SQL:select user.name from user,score where user.id = score.id and score.num 60

    Analyzer模块

    通过解析后ULP有了基本骨架,但是系统对表的字段信息是不知道的。如sum,select,join,where还有score,people都表示什么含义,此时需要基本的元数据信息schema catalog来表达这些token。最重要的元数据信息就是,

    • 表的schema信息,主要包括表的基本定义(表名、列名、数据类型)、表的数据格式(json、text、parquet、压缩格式等)、表的物理位置
    • 基本函数信息,主要是指类信息

    Analyzer会再次遍历整个AST,对树上的每个节点进行数据类型绑定以及函数绑定,比如people词素会根据元数据表信息解析为包含age、id以及name三列的表,people.age会被解析为数据类型为int的变量,sum会被解析为特定的聚合函数,

    环球彩票登陆 1

    词义注入

    //org.apache.spark.sql.catalyst.analysis.Analyzer.scala
      lazy val batches: Seq[Batch] = Seq( //不同Batch代表不同的解析策略
        Batch("Substitution", fixedPoint,
          CTESubstitution,
          WindowsSubstitution,
          EliminateUnions,
          new SubstituteUnresolvedOrdinals(conf)),
        Batch("Resolution", fixedPoint,
          ResolveTableValuedFunctions ::
          ResolveRelations ::  //通过catalog解析表或列基本数据类型,命名等信息
          ResolveReferences :: //解析从子节点的操作生成的属性,一般是别名引起的,比如people.age
          ResolveCreateNamedStruct ::
          ResolveDeserializer ::
          ResolveNewInstance ::
          ResolveUpCast ::
          ResolveGroupingAnalytics ::
          ResolvePivot ::
          ResolveOrdinalInOrderByAndGroupBy ::
          ResolveMissingReferences ::
          ExtractGenerator ::
          ResolveGenerate ::
          ResolveFunctions :: //解析基本函数,如max,min,agg
          ResolveAliases ::
          ResolveSubquery :: //解析AST中的字查询信息
          ResolveWindowOrder ::
          ResolveWindowFrame ::
          ResolveNaturalAndUsingJoin ::
          ExtractWindowExpressions ::
          GlobalAggregates :: //解析全局的聚合函数,比如select sum(score) from table
          ResolveAggregateFunctions ::
          TimeWindowing ::
          ResolveInlineTables ::
          TypeCoercion.typeCoercionRules   
          extendedResolutionRules : _*),
        Batch("Nondeterministic", Once,
          PullOutNondeterministic),
        Batch("UDF", Once,
          HandleNullInputsForUDF),
        Batch("FixNullability", Once,
          FixNullability),
        Batch("Cleanup", fixedPoint,
          CleanupAliases)
      )
    

    二、Selectivity

    Selectivity :谓词的过滤条件返回的结果的行数占未加谓词过滤条件的行数

    公式:=环球彩票登陆 2

    范围0-1,值越小,说明 选择性越好 返回的cardinality 越小;值越大,选择性越差,返回的cardinality 越大。

    未加任何谓词条件结果集: original cardinality,增加谓词条件为:computed cardinality。

    computed cardinality=original cardinality*selectivity

    在列上没有NULL或者直方图的情况下,selectivity取值

    SELECTIVITY=环球彩票登陆 3

    NUM_DISTINCT :表示为列中不同值的个数

    逻辑查询计划

    0. Overview
    1. Catalyst工作流程
    2. Parser模块
    3. Analyzer模块
    4. Optimizer模块
    5. SparkPlanner模块
    6. Job UI
    7. Reference
    

    一、优化类型:RBO和CBO

    (一)、RBO

    RBO基于规则的优化器access paths优先级:

    • RBO Path 1: Single Row by Rowid
    • RBO Path 2: Single Row by Cluster Join
    • RBO Path 3: Single Row by Hash Cluster Key with Unique or Primary Key
    • RBO Path 4: Single Row by Unique or Primary Key
    • RBO Path 5: Clustered Join
    • RBO Path 6: Hash Cluster Key
    • RBO Path 7: Indexed Cluster Key
    • RBO Path 8: Composite Index
    • RBO Path 9: Single-Column Indexes
    • RBO Path 10: Bounded Range Search on Indexed Columns
    • RBO Path 11: Unbounded Range Search on Indexed Columns
    • RBO Path 12: Sort Merge Join
    • RBO Path 13: MAX or MIN of Indexed Column
    • RBO Path 14: ORDER BY on Indexed Column
    • RBO Path 15: Full Table Scan

    注意在不违反如上优先级的前提下,若有2个优化级一样的索引可用,则RBO会选择晚建的那个索引, 解决方法是重建你想要让RBO使用的那个索引,或者使用CBO……..

    (二)、optimizer_mode :优化器的模式

    1、RULE:使用rbo的规则

    2、CHOOSE:9i中默认值,SQL语句全部的对象中无统计信息,使用RBO,其他使用CBO

    3、FIRST_ROWS_n(n=1,10,100,1000):CBO会把哪些能够最快响应速度返回的成本设置为很小的值

    4、ALL_ROWS:oracle10g 以后的默认值,会使用CBO来解析SQL,计算各个执行路径中的成本值最佳的吞吐量(最小的I/O和CPU资源)


    二、结果集

    执行计划中row,CBO评估的cardinality


    三、访问数据的方法

    (一)、访问表的方法:全表扫描和rowid访问

    全表扫描:从高水位线下全部数据块读取,DELETE不会下降高水位线

    ROWID访问:通过物理存储地址直接访问,rowid是个伪列,但是他能快速的定位的数据文件、块、行

    scott@GULL> select empno,rowid ,dbms_rowid.rowid_relative_fno(rowid)||'_'||dbms_rowid.rowid_block_number(rowid)||'_'||dbms_rowid.rowid_row_number(rowid) location_row from emp;
    
         EMPNO ROWID              LOCATION_ROW
    ---------- ------------------ ------------------------------
          7369 AAASZHAAEAAAACXAAA 4_151_0
          7499 AAASZHAAEAAAACXAAB 4_151_1
          7521 AAASZHAAEAAAACXAAC 4_151_2
          7566 AAASZHAAEAAAACXAAD 4_151_3
          7654 AAASZHAAEAAAACXAAE 4_151_4
          7698 AAASZHAAEAAAACXAAF 4_151_5
          7782 AAASZHAAEAAAACXAAG 4_151_6
          7788 AAASZHAAEAAAACXAAH 4_151_7
          7839 AAASZHAAEAAAACXAAI 4_151_8
          7844 AAASZHAAEAAAACXAAJ 4_151_9
          7876 AAASZHAAEAAAACXAAK 4_151_10
          7900 AAASZHAAEAAAACXAAL 4_151_11
          7902 AAASZHAAEAAAACXAAM 4_151_12
          7934 AAASZHAAEAAAACXAAN 4_151_13
    

    (二)、索引访问

    索引访问的成本:一部分时访问相关的B树索引的成本,另一个成本是回表的成本(根据索引中的rowid)

    1、索引唯一性扫描(index unique scan):建立是唯一索引,能建立唯一索引的一定要建立唯一索引

    2、索引范围扫描(index range scan):谓词条件中>、<等

    3、索引全扫描(index full scan):扫描目标索引中所有的块的所有索引行。从最左的叶子节点读到底,因为叶子是一个双向链表

    • 索引全扫描的执行结果是有有序的,并且是按照该索引的索引键值列来排序,这也意味走索引全扫描能够既达到排序的效果,又同时避免了对该索引的索引键值列的真正的排序操作。
    • 索引全扫描时有序的就决定了不能够并行执行,索引全扫描时单块读
    • oracle中能做索引全扫描的前提条件是目标索引至少有一个索引键值列的属性是NOT NULL

    4、索引快速全扫描(INDEX FAST FULL SCAN)

    索引全扫描类似,读取所有叶子块的索引行

    与全索引扫描不同点

    • 索引快速全扫描只适用于CBO
    • 索引快速全扫描可以使用多块读,也可以并行执行
    • 索引快速全扫描的执行结果不一定是有序的

    5、索引跳跃式扫描(INDEX SKIP SCAN)

    适用复合B数索引,谓词中的过滤条件不是以索引前导列。

    只是对前导列做distinct:如create index ind_1 ON emp(job,empno)

    Select * from emp where empno=7499

    如果job有两个CLERK,SALESMAN

    等同的语句

    Select * from emp where job='CLERK' AND empno=7499
    UNION ALL
    Select * from emp where job='SALESMAN' AND empno=7499
    
    oracle中的索引跳跃式扫描仅仅适用那些目标索引前导列的distinct值数量较少、后续非前导列的可选择性又非常好的情形,因为索引跳跃式扫描的执行效率一定会随着目标索引前导列的distinct值数量的递增而递减
    

    四、表连接

    (一)、表连接顺序

    不管目标SQL中有多少个表做表连接,ORACLE在实际执行都是先做两两做表连接,在依次执行这样的两两表连接过程,直到目标SQL中所有表都已经连接完毕。

    表连接很重要的是驱动表(outer table)和被驱动表(inner table)。

    (二)、表连接方法

    • 嵌套循环连接(nested loop)

         1、如果驱动表所对应的驱动结果集的记录数较少,同时在被驱动表的连接列上又存在唯一性索引(或者在被驱动表的连接列上存在选择性很好的非唯一性索引),那么此时使用嵌套循环连接的执行效率非常高。

         2、大表也可以作为驱动表,关键看大表的谓词条件是否可以把驱动表的结果集的数据量下降下来

    • 哈希连接(hash join)

         1、哈希连接不一定会排序,或者说大多数情况下都不需要排序

         2、哈希连接的驱动表所对应的连接列的可选择性应尽可能好,因为这个可选择性会影响对应hash bucket中的记录数,而hash bucket中的记录数又会直接影响从该hash bucket中查询匹配记录的记录。如果一个hash bucket里所包含的记录数过多,则可能或严重降低所对应哈希连接的执行效率,此时典型的表现就是该哈希连接执行了很多时间都没有结束,数据库所在数据库服务器上的CPU占用率很高,但目标SQL所消耗的逻辑读却很低,因为此时大部分时间都耗费在了遍历上述Hash Bucket里的所有记录上,而遍历Hash Bucket里的记录这个动作发生在PGA的工作区里,所以不耗费逻辑读。

         3、哈希连接只适用于CBO,它也只能用于等值连接条件(即使是哈希反连接,Oracle实际上也是讲其转换成了等价的等值连接)。

         4、哈希连接很适合小表和大表之间做连接且连接结果集的记录数较多的情形,特别是在小表的连接列的可选择性非常好的情况下,这时候哈希连接的执行时间就可以近似看作和全表扫描那个大表所耗费的时间相当。

         5、当两个表做哈希连接时,如果在施加目标SQL中指定的谓词条件(如果有的话)后得到的数据量较小的那个结果集所对应的hash table、 能够完全容纳在内存中(PGA的工作区),则此时的哈希连接的执行效率会非常高

    • 排序合并连接(merge jion)

        1、通常情况下,排序合并连接的执行效率会远不如哈希连接,但前者的使用范围更广,因为哈希连接通常只能用于等值连接条件,而排序合并连接还能用于其他连接条件(<,<=,>,>=)

        2、通常情况下,排序合并连接并不适合OLTP类型的系统,器本质原因是因为对于OLTP类型的系统而言,排序很昂贵的操作,当然,如果能避免排序操作,那么即使是OLTP类型的系统,也还是可以使用排序合并连接的。

        3、排序合并连接并不存在驱动表的概念

    • 笛卡尔积连接(Cartesian join)

         1、无任何连接条件,在执行计划中有cartesian,通常来说,有笛卡尔积,sql语句是有问题的

    (三)、表连接的类型

    1、内连接(Inner JOIN)

     
    
    --使用=
    select * from emp a , dept b  where a.deptno=b.deptno
    --join
    select * from emp a join dept b on a.deptno=b.deptno
    

    2、外连接(outer join)

    左连接--使用( )
    select * from emp a,dept b where a.deptno=b.deptno( )
    --使用left join
    select * from emp a left outer join dept b on a.deptno=b.deptno
    
    右连接
    --使用( )
    select * from emp a,dept b where a.deptno( )=b.deptno
    --使用left join
    select * from emp a right outer join dept b on a.deptno=b.deptno
    

    外连接的驱动表以( )对面的表,如以上左连接,驱动表为a,右连接的驱动表为b

    3、反连接(anti join)

    连接中not in、not exists 、<>

    sql A:select * from emp a WHERE A.DEPTNO NOT  IN (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)
    
    sql B:select * from emp a WHERE NOT EXISTS (SELECT 1 FROM dept b where a.deptno=b.deptno)
    
    sql C:select * from emp a WHERE A.DEPTNO <> all (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)
    
     
    

    4、半连接(semi join)

    连接中用in,exists,any

    select * from emp a WHERE A.DEPTNO   IN (SELECT DEPTNO FROM dept b where a.deptno=b.deptno)
    
    select * from emp a WHERE  EXISTS (SELECT 1 FROM dept b where a.deptno=b.deptno)
    
    select * from emp a WHERE A.DEPTNO =any(SELECT DEPTNO FROM dept b where a.deptno=b.deptno)
    
     
    

    5、星形连接

    在OLTP基本不会用到,在OLAP中用到

    参考:崔华《基于ORACLE的SQL优化》

    Apply:子查询,如select * from (select id,name from table1) as t中的(select id,name from table1) as t。可以进行嵌套查询。

    Overview

    Spark SQL的核心是Catalyst优化器,是以一种新颖的方式利用Scala的的模式匹配和quasiquotes机制来构建的可扩展查询优化器。

    环球彩票登陆 4

    sparkSql pipeline

    sparkSql的catalyst优化器是整个sparkSql pipeline的中间核心部分,其执行策略主要两方向,

    1. 基于规则优化/Rule Based Optimizer/RBO
      • 一种经验式、启发式优化思路
      • 对于核心优化算子join有点力不从心,如两张表执行join,到底使用broadcaseHashJoin还是sortMergeJoin,目前sparkSql是通过手工设定参数来确定的,如果一个表的数据量小于某个阈值(默认10M?)就使用broadcastHashJoin
        • nestedLoopsJoin,P,Q双表两个大循环, O(M*N)
        • sortMergeJoin是P,Q双表排序后互相游标
        • broadcastHashJoin,PQ双表中小表放入内存hash表,大表遍历O(1)方式取小表内容
    2. 基于代价优化/Cost Based Optimizer/CBO
      • 针对每个join评估当前两张表使用每种join策略的代价,根据代价估算确定一种代价最小的方案
      • 不同physical plans输入到代价模型(目前是统计),调整join顺序,减少中间shuffle数据集大小,达到最优输出

    三、transitivity(可传递性)

    CBO会对现有的sql语句做等价转换,谓词条件、字段连接


    优化器基础概念

    环球彩票登陆 5

    Parser模块

    将sparkSql字符串切分成一个一个token,再根据一定语义规则解析为一个抽象语法树/AST。Parser模块目前基本都使用第三方类库ANTLR来实现,比如Hive,presto,sparkSql等。

    环球彩票登陆 6

    parser切词

    Spark 1.x版本使用的是Scala原生的Parser Combinator构建词法和语法分析器,而Spark 2.x版本使用的是第三方语法解析器工具ANTLR4。

    Spark2.x SQL语句的解析采用的是ANTLR4,ANTLR4根据语法文件SqlBase.g4自动解析生成两个Java类:词法解析器SqlBaseLexer和语法解析器SqlBaseParser。

    SqlBaseLexer和SqlBaseParser都是使用ANTLR4自动生成的Java类。使用这两个解析器将SQL字符串语句解析成了ANTLR4的ParseTree语法树结构。然后在parsePlan过程中,使用AstBuilder.scala将ParseTree转换成catalyst表达式逻辑计划LogicalPlan。


    CBO基础概念

    CBO:评估 I/O,CPU,网络(DBLINK)等消耗的资源成本得出

    选择、投影、连接就是最基本的算子

    Reference

    • Deep Dive Into Catalyst: Apache Spark’s Optimizer
    • Spark SQL Optimization – Understanding the Catalyst Optimizer
    • Catalyst——Spark SQL中的函数式关系查询优化框架
    • SparkSQL – 从0到1认识Catalyst
    • Spark-Catalyst Optimizer
    • sparksql执行流程分析
    • SparkSQL优化器Catalyst
    • spark catalyst source code
    • Cost-Based Optimizer in Apache Spark 2.2

    一、cardinality

    cardinality:集合中包含的记录数。实际CBO评估目标SQL执行具体步骤的记录数,cardinality和成本是相关的,cardinality越大,执行步骤中的成本就越大

    Sort:排序,如select * from table1 order by id里面的order by。无序的数据通过这个算子处理后,输出有序的数据。

    SparkPlanner模块

    至此,OLP已经得到了比较完善的优化,然而此时OLP依然没有办法真正执行,它们只是逻辑上可行,实际上spark并不知道如何去执行这个OLP。

    • 比如join只是一个抽象概念,代表两个表根据相同的id进行合并,然而具体怎么实现这个合并,逻辑执行计划并没有说明

    环球彩票登陆 7

    optimized logical plan -> physical plan

    此时就需要将左边的OLP转换为physical plan物理执行计划,将逻辑上可行的执行计划变为spark可以真正执行的计划。

    • 比如join算子,spark根据不同场景为该算子制定了不同的算法策略,有broadcastHashJoin、shuffleHashJoin以及sortMergeJoin,物理执行计划实际上就是在这些具体实现中挑选一个耗时最小的算法实现,这个过程涉及到cost model/CBO

    环球彩票登陆 8

    CBO off

    环球彩票登陆 9

    CBO on

    CBO中常见的优化是join换位,以便尽量减少中间shuffle数据集大小,达到最优输出。


    那么常见的优化规则就包括:

    Catalyst工作流程

    • Parser,利用ANTLR将sparkSql字符串解析为抽象语法树AST,称为unresolved logical plan/ULP
    • Analyzer,借助于数据元数据catalog将ULP解析为logical plan/LP
    • Optimizer,根据各种RBO,CBO优化策略得到optimized logical plan/OLP,主要是对Logical Plan进行剪枝,合并等操作,进而删除掉一些无用计算,或对一些计算的多个步骤进行合并

    Projection:投影,指搜索的列,如select name from table1 where id = 1中的列name

    Optimizer模块

    Optimizer是catalyst的核心,分为RBO和CBO两种。
    RBO的优化策略就是对语法树进行一次遍历,模式匹配能够满足特定规则的节点,再进行相应的等价转换,即将一棵树等价地转换为另一棵树。SQL中经典的常见优化规则有,

    • 谓词下推(predicate pushdown)
    • 常量累加(constant folding)
    • 列值裁剪(column pruning)
    • Limits合并(combine limits)

    环球彩票登陆 10

    由下往上走,从join后再filter优化为filter再join

    环球彩票登陆 11

    从`100 80`优化为`180`,避免每一条record都需要执行一次`100 80`的操作

    环球彩票登陆 12

    剪裁不需要的字段,特别是嵌套里面的不需要字段。如只需people.age,不需要people.address,那么可以将address字段丢弃

    //@see http://blog.csdn.net/oopsoom/article/details/38121259
    //org.apache.spark.sql.catalyst.optimizer.Optimizer.scala
      def batches: Seq[Batch] = {
        // Technically some of the rules in Finish Analysis are not optimizer rules and belong more
        // in the analyzer, because they are needed for correctness (e.g. ComputeCurrentTime).
        // However, because we also use the analyzer to canonicalized queries (for view definition),
        // we do not eliminate subqueries or compute current time in the analyzer.
        Batch("Finish Analysis", Once,
          EliminateSubqueryAliases,
          ReplaceExpressions,
          ComputeCurrentTime,
          GetCurrentDatabase(sessionCatalog),
          RewriteDistinctAggregates) ::
        //////////////////////////////////////////////////////////////////////////////////////////
        // Optimizer rules start here
        //////////////////////////////////////////////////////////////////////////////////////////
        // - Do the first call of CombineUnions before starting the major Optimizer rules,
        //   since it can reduce the number of iteration and the other rules could add/move
        //   extra operators between two adjacent Union operators.
        // - Call CombineUnions again in Batch("Operator Optimizations"),
        //   since the other rules might make two separate Unions operators adjacent.
        Batch("Union", Once,
          CombineUnions) ::
        Batch("Subquery", Once,
          OptimizeSubqueries) ::
        Batch("Replace Operators", fixedPoint,
          ReplaceIntersectWithSemiJoin,
          ReplaceExceptWithAntiJoin,
          ReplaceDistinctWithAggregate) ::
        Batch("Aggregate", fixedPoint,
          RemoveLiteralFromGroupExpressions,
          RemoveRepetitionFromGroupExpressions) ::
        Batch("Operator Optimizations", fixedPoint,
          // Operator push down
          PushProjectionThroughUnion,
          ReorderJoin,
          EliminateOuterJoin,
          PushPredicateThroughJoin, //谓词下推之一
          PushDownPredicate, //谓词下推之一
          LimitPushDown,
          ColumnPruning, //列值剪裁,常用于聚合操作,join左右孩子操作,合并相邻project列
          InferFiltersFromConstraints,
          // Operator combine
          CollapseRepartition,
          CollapseProject,
          CollapseWindow,
          CombineFilters, //谓词下推之一,合并两个相邻的Filter。合并2个节点,就可以减少树的深度从而减少重复执行过滤的代价
          CombineLimits, //合并Limits
          CombineUnions,
          // Constant folding and strength reduction
          NullPropagation,
          FoldablePropagation,
          OptimizeIn(conf),
          ConstantFolding, //常量累加之一
          ReorderAssociativeOperator,
          LikeSimplification,
          BooleanSimplification, //常量累加之一,布尔表达式的提前短路
          SimplifyConditionals,
          RemoveDispensableExpressions,
          SimplifyBinaryComparison,
          PruneFilters,
          EliminateSorts,
          SimplifyCasts,
          SimplifyCaseConversionExpressions,
          RewriteCorrelatedScalarSubquery,
          EliminateSerialization,
          RemoveRedundantAliases,
          RemoveRedundantProject) ::
        Batch("Check Cartesian Products", Once,
          CheckCartesianProducts(conf)) ::
        Batch("Decimal Optimizations", fixedPoint,
          DecimalAggregates) ::
        Batch("Typed Filter Optimization", fixedPoint,
          CombineTypedFilters) ::
        Batch("LocalRelation", fixedPoint,
          ConvertToLocalRelation,
          PropagateEmptyRelation) ::
        Batch("OptimizeCodegen", Once,
          OptimizeCodegen(conf)) ::
        Batch("RewriteSubquery", Once,
          RewritePredicateSubquery,
          CollapseProject) :: Nil
      }
    

    Join:连接,如select * from table1 table2 where table1.name=table2.name就是把两个表做Join。连接条件是最简单的等值连接,当然还有其他我们熟知的inner join,left join,right join等等

    Job UI

    环球彩票登陆 13

    sp.prepare.PrepareController

    • WholeStageCodegen,将多个operators合并成一个java函数,从而提高执行速度
    • Project,投影/只取所需列
    • Exchange,stage间隔,产生了shuffle

    而优化需要做的事情就是改变逻辑算子组成的逻辑查询计划,使它执行时的代价尽量的小。当然优化规则就是我们前面提到的那些了。

    other

    Optimizer是catalyst工作最后阶段了,后面生成physical plan以及执行,主要是由sparkSql来完成。

    • SparkPlanner
      • 优化后的逻辑执行计划OLP依然是逻辑的,并不能被spark系统理解,此时需要将OLP转换成physical plan
      • 从逻辑计划/OLP生成一个或多个物理执行计划,基于成本模型cost model从中选择一个
    • Code generation
      • 生成Java bytecode然后在每一台机器上执行,形成RDD graph/DAG

    列裁剪

    记录一下个人对sparkSql的catalyst这个函数式的可扩展的查询优化器的理解,目录如下,

    user,score对应最下面的DataSource,负责读取数据。


    Aggregation:分组,如select sum from table1 group by name中的group by。按照某些列进行分组,分组后可以进行一些聚合操作,比如Max、Min、Sum、Count、Average等等

    变成查询计划之后如图所示:

    Selection:选择,如select name from table1 where id = 1中的where后的过滤条件。

    谓词下推

    既然由逻辑算子那么就有物理算子,物理算子和逻辑算子的不同在于,一个逻辑算子可能对应多种的物理算子的实现。比如Join的物理算子实现可以用NestLoop Join、HashJoin、MergeSort Join等,Aggregation可以用Hash或者排序后分组的不同做法,DataSource可以直接扫描全表也可以利用索引读取数据等等。

    其他

    DataSource:数据源,也就是我们SQL语句中的表。select name from table1中的table1。

    逻辑查询计划就是SQL语句通过SQL解析之后由各个逻辑算子组成的树状结构。

    在上面由一个Join,将两个表的结果按user.id=score.id连接

    我们提到了两种SQL优化器,分别是RBO和CBO。那么无论是RBO,还是CBO都包含了一系列优化规则,这些优化规则可以对关系表达式进行等价转换,从而寻找最优的执行计划。

    在上述这些优化规则的基础上,就能够对关系表达式做出相应的等价转换,从而生成执行计划。本篇文章先从优化规则的基础概念逻辑算子开始讲起,后续会介绍各个优化规则。

    再按score.num 60 做一个Selection过滤

    常量传播

    逻辑算子

    所以我们常说的:“查询慢,加个索引啊”,要确保逻辑查询计划对应的物理计划走索引查询才行。

    最后将user.name做投影(Projection)

    投影消除

    最大最小消除

    本文由环球彩票登陆发布于环球彩票登陆,转载请注明出处:斯Parker SQL Catalyst优化器环球彩票登陆

    关键词: 环球彩票登陆 过程 sql spark 算子