美文网首页
spark启用CBO

spark启用CBO

作者: JX907 | 来源:发表于2021-02-07 17:19 被阅读0次

    ● RBO (Rule-Based Optimization)
    RBO使用的规则是根据经验形成的,只要按照这个规则去写SQL语句,无论数据表中的内容怎样、数据分布如何,都不会影响到执行计划。
    ● CBO (Cost-Based Optimization)
    CBO是根据实际数据分布和组织情况,评估每个计划的执行代价,从而选择代价最小的执行计划。
    目前Spark的优化器都是基于RBO的,已经有数十条优化规则,例如谓词下推、常量折叠、投影裁剪等,这些规则是有效的,但是它对数据是不敏感的。导致的一个问题就是数据表中数据分布发生变化时,RBO是不感知的,基于RBO生成的执行计划不能确保是最优的。而CBO的重要作用就是能够根据实际数据分布估算出SQL语句,生成一组可能被使用的执行计划中代价最小的执行计划,从而提升性能。
    目前CBO主要的优化点是Join算法选择。举个简单例子,当两个表做Join操作,如果其中一张原本很大的表经过Filter操作之后结果集小于BroadCast的阈值,在没有CBO情况下是无法感知大表过滤后变小的情况,采用的是SortMergeJoin算法,涉及到大量Shuffle操作,很耗费性能;在有CBO的情况下是可以感知到结果集的变化,采用的是BroadcastHashJoin算法,会将过滤后的小表BroadCast到每个节点,转变为非Shuffle操作,从而大大提高性能。

    环境说明:
    spark2.4.0
    hive1.2.1

    1、参数设置
    sparkConf.set("spark.sql.cbo.enabled", "true")
    sparkConf.set("spark.sql.cbo.joinReorder.enabled", "true")
    2、统计分析
    对需要查询的表执行统计分析命令,结果会存储到hive元数据表table_params中,cbo在运行时会读取size、rowCount等指标。
    不需要每次都执行,每天定时执行所有表的统计分析即可
    sparkSession.sql("ANALYZE TABLE dw_dim.date_dim COMPUTE STATISTICS").collect();
    sparkSession.sql("ANALYZE TABLE lucky_order.t_order_commodity COMPUTE STATISTICS").collect();
    sparkSession.sql("ANALYZE TABLE lucky_order.t_order COMPUTE STATISTICS").collect();
    sparkSession.sql("ANALYZE TABLE lucky_order.t_order_express COMPUTE STATISTICS").collect();

    3、验证
    debug调试,CostBasedJoinRecorder#recorder方法能够进入if分支:
    if (items.size > 2 && items.size <= conf.joinReorderDPThreshold && conditions.nonEmpty &&
    items.forall(_.stats.rowCount.isDefined)) {
    JoinReorderDP.search(conf, items, conditions, output)
    }

    4、实例
    实例1
    sql语句:
    select
    c.id
    from
    lucky_order.t_order_commodity c
    inner join lucky_order.t_order o on o.id = c.order_id
    inner join lucky_order.t_order_express express on express.order_id = o.id
    inner join dw_dim.date_dim dim on dim.dt = express.dt
    where express.dt = 2019-06-20
    启用CBO前执行逻辑:
    <meta charset="utf-8">

    1.png

    启用CBO后执行逻辑:


    2.png

    实例2
    select
    c.id
    from
    lucky_order.t_order_commodity c
    left join lucky_order.t_order o on o.id = c.order_id
    left join lucky_order.t_order_express express on express.order_id = o.id
    left join dw_dim.date_dim dim on dim.dt = express.dt
    where express.dt = 2019-06-20
    启用CBO前执行逻辑:


    3.png

    启用CBO后执行逻辑:


    4.png

    相关文章

      网友评论

          本文标题:spark启用CBO

          本文链接:https://www.haomeiwen.com/subject/xqwztltx.html