You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spark2.4.4读取Hive2.3.3 UNION ALL生成ORC表无数据问题咨询

问题1:为什么Spark无法识别表1的数据?

Spark 2.4.4默认读取非分区Hive表时,仅扫描表存储根目录下的直接数据文件,不会递归遍历子目录。你提供的目录结构里,表1的所有ORC数据文件都存放在1/、2/等子目录下,根目录没有任何数据文件,Spark扫描时判定表为空,因此返回0行数据且无报错。
而Hive Beeline默认开启了目录递归扫描配置,因此可以正常读取嵌套子目录下的文件,返回全量数据。

问题2:为什么Hive为表1生成了结构复杂的5个文件,为表2仅生成结构简单的4个文件?

你指定了Hive执行引擎为MR,CTAS(Create Table As Select)语句的任务输出结构和查询的stage数量直接相关:

  • 表1的查询包含UNION ALL,会拆分为两个独立的子查询任务执行,每个子任务的输出默认会写入独立的子目录:第一个子查询(explode逻辑)的输出存到1/目录下,第二个子查询(null值处理逻辑)的输出存到2/目录下,子查询内部如果有多级stage还会额外嵌套子目录,就形成了你看到的多层嵌套结构。
  • 表2的查询仅用单条SELECT加outer explode实现逻辑,没有多任务合并的步骤,因此所有输出文件直接写入表的根目录,没有嵌套子目录,文件数量就是当前查询的并行度对应的输出数。

问题3:存储结构差异是否会影响Spark的读取过程?

会,就是这个存储结构差异直接导致表1读取失败。
Spark对非分区表的默认读取逻辑仅识别根目录下的直接文件,嵌套子目录下的文件默认不会被扫描到。如果需要兼容这种目录结构,可以在Spark任务启动时添加配置:

spark.sql.files.recursiveFileLookup=true

或者读取时直接指定通配符路径扫描子目录:

Dataset<Row> df = sparkSession.read().orc("/user/hive/warehouse/test.db/table1/*/*");

也可以在建表时添加Hive参数避免生成嵌套目录:

set hive.merge.job.results=true;
create table test.table1 stored as orc as
-- 你的查询逻辑

该参数会将多个任务的输出合并后写入表根目录,不会生成嵌套子目录。


内容的提问来源于stack exchange,提问作者Uroboros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 09:15:01