临时视图仅在创建它的sparksession内可见,生命周期与其绑定;全局视图通过createglobaltempview()创建,作用域为整个spark应用,但必须用global_temp.前缀访问。

临时视图只在当前SparkSession内可见
调用 createOrReplaceTempView() 创建的视图,生命周期绑定到创建它的那个 SparkSession 实例。一旦该 session 关闭或被 GC 回收,视图就不可查;更重要的是,哪怕你用 spark.newSession() 新建一个 session,它也完全看不到之前创建的临时视图。
常见错误现象:table or view not found: xxx —— 尤其在单元测试里反复 newSession 时容易踩坑;或者在 notebook 中切换 kernel 后发现视图“消失”了。
- 适用场景:交互式探索、单任务临时分析、不需要跨 stage 共享结果的 ETL 步骤
- 不能跨会话访问,也不需要加前缀,直接
SELECT * FROM my_view - 底层不依赖 Hive Metastore,纯内存注册,启动快、无额外配置要求
全局视图必须用 global_temp 前缀访问
createGlobalTempView() 注册的视图,作用域是整个 Spark application(即 JVM 进程),所有 SparkSession 实例都能看到它——但必须显式加上 global_temp. 前缀,否则报错。
典型错误写法:spark.sql("SELECT * FROM stu") → 报错;正确写法:spark.sql("SELECT * FROM global_temp.stu")。这个前缀不是可选的,是强制语法要求。
- 跨 session 可用:比如你在一个 session 中建表,在另一个 session(甚至不同线程)中查它
- 底层仍走内存注册,但 Spark 内部用
global_temp这个固定 catalog 名管理,类似一个命名空间 - 不依赖 Hive 配置,但注意:如果启用了 Hive 支持,
global_temp仍和 Hive catalog 完全隔离,不会冲突
两者都不存数据,只是逻辑映射
无论是 createTempView() 还是 createGlobalTempView(),注册的都只是对原始 DataFrame 的引用,不触发任何计算,也不落盘。查询时才真正执行 DAG,和数据库里的「视图」语义一致——不是临时表,没有物理存储。
这意味着:如果你源 DataFrame 是从文件读取的,每次查视图都会重新 scan 文件;如果源是已缓存的 DataFrame,则复用缓存;如果源是未缓存且计算代价高,视图反复查就会反复算。
- 别指望靠视图来“加速”——要提速得先
cache()或persist()源 DataFrame - 视图不支持 DML(如 INSERT/UPDATE),也不能被 TRUNCATE,本质是只读别名
- 重名覆盖安全:两个方法都叫
createOrReplaceXXX,同名注册会静默替换,不会报错
为什么不用 Hive 表而选视图?
当你的数据生命周期短、不需跨 application 复用、又不想写 DDL 或配 Hive Metastore 时,视图就是最轻量的选择。但要注意:全局视图虽然跨 session,却不跨 application——Spark job 结束后就清空,没法像 Hive 表那样长期存在。
最容易被忽略的一点:全局视图的 catalog 名 global_temp 是硬编码的,无法自定义;而且它不支持分区、不支持谓词下推优化(因为没 schema 推导能力),这些限制在做复杂 ETL 链路时会突然暴露出来。











