配置列统计值直方图Histogram用以增强CBO准确度
配置场景
Spark优化sql的执行,一般的优化规则都是启发式的优化规则,启发式的优化规则,仅仅根据逻辑计划本身的特点给出优化,没有考虑数据本身的特点,也就是未考虑算子本身的执行代价。Spark在2.2中引入了基于代价的优化规则(CBO)。CBO会收集表和列的统计信息,结合算子的输入数据集来估计每个算子的输出条数以及字节大小,这些就是执行一个算子的代价。
CBO会调整执行计划,来最小化端到端的查询时间,中心思路2点:
- 尽早过滤不相关的数据。
- 最小化每个算子的代价。
CBO优化过程分为2步:
- 收集统计信息。
- 根据输入的数据集估算特定算子的输出数据集。
表级别统计信息包括:记录条数;表数据文件的总大小。
列级别统计信息包括:唯一值个数;最大值;最小值;空值个数;平均长度;最大长度;直方图。
有了统计信息后,就可以估计算子的执行代价了。常见的算子包括过滤条件Filter算子和Join算子。
直方图为列统计值的一种,可以直观的描述列数据的分布情况,将列的数据从最小值到最大值划分为事先指定数量的槽位(bin),计算各个槽位的上下界的值,使得全部数据都确定槽位后,所有槽位中的数据数量相同(等高直方图)。有了数据的详细分布后,各个算子的代价估计能更加准确,优化效果更好。
该特性可以通过下面的配置项开启:
spark.sql.statistics.histogram.enabled:指定是否开启直方图功能,默认为false。
配置参数
登录FusionInsight Manager系统,选择“集群 > 服务 > Spark > 配置”,单击“全部配置”,搜索以下参数。
参数 |
说明 |
默认值 |
取值范围 |
---|---|---|---|
spark.sql.cbo.enabled |
开启CBO来估计执行计划的统计值。 |
false |
[true,false] |
spark.sql.cbo.joinReorder.enabled |
开启CBO连接重排序。 |
false |
[true,false] |
spark.sql.cbo.joinReorder.dp.threshold |
动态规划算法中允许的最大的join节点数量。 |
12 |
>=1 |
spark.sql.cbo.joinReorder.card.weight |
在重连接执行计划代价比较中维度(行数)所占的比重:行数 * 比重 + 文件大小 *(1 - 比重)。 |
0.7 |
0-1 |
spark.sql.statistics.size.autoUpdate.enabled |
开启当表的数据发生变化时,自动更新表的大小信息。注意如果表的数据文件总数量非常多时,这个操作会非常耗费资源,减慢对数据的操作速度。 |
false |
[true,false] |
spark.sql.statistics.histogram.enabled |
开启后,当统计列信息时,会生成直方图。直方图可以提高估计准确度,但是收集直方图信息会有额外工作量。 |
false |
[true,false] |
spark.sql.statistics.histogram.numBins |
生成的直方图的槽位数。 |
254 |
>=2 |
spark.sql.statistics.ndv.maxError |
在生成列级别统计信息时,HyperLogLog++算法允许的最大估计误差。 |
0.05 |
0-1 |
spark.sql.statistics.percentile.accuracy |
在生成等高直方图时百分位估计的准确率。该值越大意味着越准确。估计错误值可以通过(1.0 / 百分位估计的准确率)来得到。 |
10000 |
>=1 |
- 如果希望直方图可以在CBO中生效,需要满足下面的条件:
- spark.sql.statistics.histogram.enabled : true,默认是false,修改为true开启直方图功能。
- spark.sql.cbo.enabled : true,默认为false,修改为true开启CBO。
- spark.sql.cbo.joinReorder.enabled : true,默认为false,修改为true开启连接重排序。
- 若使用客户端提交任务,“spark.sql.cbo.enabled”、“spark.sql.cbo.joinReorder.enabled”、“spark.sql.cbo.joinReorder.dp.threshold”、“spark.sql.cbo.joinReorder.card.weight”、“spark.sql.statistics.size.autoUpdate.enabled”、“spark.sql.statistics.histogram.enabled”、“spark.sql.statistics.histogram.numBins”、“spark.sql.statistics.ndv.maxError”、“spark.sql.statistics.percentile.accuracy”参数修改后需要重新下载客户端才能生效。