Spark 2.2.1启用CBO后执行查询未显示统计信息求助
问题分析与解决方案
你在Spark 2.2.1里启用CBO后,执行了ANALYZE TABLE但explain看不到统计信息的问题,我帮你梳理下原因和解决办法:
为啥统计信息没显示?
Spark 2.2.x版本的CBO和统计机制有几个小局限:
- 默认ANALYZE只做表级统计:你执行的
ANALYZE TABLE events COMPUTE STATISTICS只会收集表的总行数这类表级数据,不会自动生成eventID这类列的统计信息。没有列统计的话,CBO没法基于这个列做优化,执行计划里自然也看不到相关内容。 - explain的展示限制:Spark 2.2.x的
explain(true)本身就不会主动展示已有的表/列统计,哪怕统计已经生成了,你得换个方式去验证。 - Parquet表的统计兼容性问题:早期Spark对Parquet表的统计收集支持不够完善,有时候就算跑了ANALYZE,统计也可能没正确写入元数据。
具体解决步骤
1. 收集列级统计
要生成eventID的统计,得明确指定列来执行ANALYZE:
// 收集指定列的统计,你可以加其他需要的列 spark.sql("ANALYZE TABLE events COMPUTE STATISTICS FOR COLUMNS eventID") // 或者直接收集所有列的统计 spark.sql("ANALYZE TABLE events COMPUTE STATISTICS FOR ALL COLUMNS")
2. 验证统计是否真的生成了
在Spark 2.2.1里,你可以查information_schema来确认:
spark.sql("SELECT column_name, num_distinct, lower_bound, upper_bound FROM information_schema.columns WHERE table_name = 'events' AND column_name = 'eventID'").show(false)
如果结果里num_distinct这些字段有数值,说明统计已经成功生成了。
3. 确保CBO配置全开启
除了spark.sql.cbo.enabled,还可以开启几个辅助配置来强化CBO效果:
spark.conf.set("spark.sql.cbo.joinReorder.enabled", true) // 如果你的查询涉及join,开启这个能让CBO优化join顺序 spark.conf.set("spark.sql.statistics.fallBackToHdfs", true) // 当统计缺失时,用HDFS文件大小做 fallback 统计
4. 查看统计的替代方式
既然2.2.x的explain不展示统计,你可以试试这两种方法:
- 打开Spark UI的SQL标签,找到对应的查询,查看执行计划的详情,里面能看到统计相关内容;
- 通过Catalog API获取表的元数据:
val tableMeta = spark.catalog.getTable("default.events") println("表级统计:" + tableMeta.stats)
额外提示
Spark 2.2.1确实是比较老的版本了,后续的2.3+版本对CBO和统计展示做了不少优化,比如explain会直接显示统计信息,统计收集的兼容性也更好。如果条件允许,升级版本能从根本上减少这类问题。另外还要确认你的events是内部表(managed table),早期Spark对外部表的统计支持可能有坑,要保证元数据存储的权限正常。
内容的提问来源于stack exchange,提问作者RockSolid
相关产品推荐
相关产品推荐

