物理计划层面,计算所有可能的物理计划的代价(考虑数据的特点:大小、分布等,考虑操作算子的特点:中间结果集的分布和大小等),选择代价小的物理执行计划。
前置条件
一定先执行特定的SQL,收集所需表和列的统计信息。
统计表
生成表级别统计信息
ANALYZE TABLE 表名 COMPUTE STATISTICS
生成sizeLnBytes(大小)和rowCount(行数)。
统计列
生成列级别统计信息
ANALYZE TABLE 表名 COMPUTE STATISTICS FOR COLUMNS 列1,列2,列3
或
DESC FORMATTED 表名 列名
生成min、max、distinct_count、max_col_len、avg_col_len等。
打开参数
spark.sql.cbo.enabled
默认为false。开启后,CBO优化器可以基于表、列的统计信息,进行估算,选择最优查询计划。
比如build侧优化、优化join类型、优化多表join顺序等。
举例
先统计好相关表及列的统计信息,命令如前置条件中所列。统计信息会持久化到元数据库中。
CBO优化前
代码
执行计划
可见使用的是sortMergeJoin。
CBO优化后
代码
sql相同
执行计划
可见使用的是BroadcastHashJoin。类似于hive的map-join。将小表广播到大表所在节点。在map端完成聚合。
开启CBO之后,按照过滤后的数据进行估算。
其他
当有多张表join的时候,可以将spark.sql.cbo.joinReorder.enabled打开,可以帮忙优化调整join的顺序。