说明
临时视图分为两种:
- 全局临时视图:作用于Spark应用程序的所有SparkSession会话
- 局部临时视图:作用于当前SparkSession会话,其他会话不可使用该临时表
全局临时视图
关键
// 创建全局临时视图
val glob=df.createOrReplaceGlobalTempView("glob_cdz")
// 查询全局临时视图,必须是 global_temp.视图名
ss.sql("select * from global_temp.glob_cdz").show()
完整代码
创建 2 个session,由其中一个session创建 全局临时视图,这2个session 都可以查询到
如果是 局部临时视图,只有创建该视图的 session 才能查询到,另一个 session 查询不到
package stdsql
import org.apache.spark.sql.SparkSession
object Std1_globel {
def main(args: Array[String]): Unit = {
val ss=SparkSession.builder().appName("test1").master("local[*]")getOrCreate()
//读取文件
val df=ss.read.csv("hdfs://hadoop1:8020/chongdianzhuang/chongdianzhuang.txt")
// val temp=df.createTempView("temp_person") //局部变量表
// sparkSession.sql("select * from temp_person").show()
//创建全局临时视图
val glob=df.createOrReplaceGlobalTempView("glob_cdz")
// 查询全局临时视图,必须是 global_temp.表名
ss.sql("select * from global_temp.glob_cdz").show()
//使用newSession()创建一个新的session,仍然可以查询全局临时视图
ss.newSession().sql("select * from global_temp.glob_cdz").show()
ss.stop()
}
}
应用场景
如果同一个应用中不同的session需要 重用 该临时表,那么 注册为全局临时表,可以避免多余的IO,提高系统的执行效率
如果只是在某个 session 中使用,只需要 注册局部临时表,可以避免不必要的内存占用
注意
将之前的 session关闭后,在另一个 session 中,查询 全局临时视图 会报错
验证:
def main(args: Array[String]): Unit = {
val sc = new SparkConf().setMaster("local[*]").setAppName("std")
//创建SparkSession
val ss: SparkSession = SparkSession.builder().config(sc).getOrCreate()
ss.conf.set("spark.sql.shuffle.partitions", 1)
val df: DataFrame = ss.read
.option("header", "false") //默认为false,表示第一行不是表头
.option("sep", ",") //列分隔符
.csv("cdz.txt") //读取本地文件
.toDF("id", "ele_num", "time", "start_time", "end_time") //设置列名,默认列名不方便查询
df.createOrReplaceGlobalTempView("cdz")
// 全局临时视图,查询时,前面必须有 global_temp,否则报错找不到
val resDF: DataFrame = ss.sql("select id, sum(ele_num) as sum from global_temp.cdz where ele_num > 100 group by id")
resDF.printSchema()
resDF.show()
ss.stop() //关闭
// 将之前的 session关闭后,在另一个 session 中,查询 全局临时视图 会报错
// java.lang.IllegalStateException: Cannot call methods on a stopped SparkContext.
val newSS = ss.newSession()
val newResDF: DataFrame = newSS.sql("select id, sum(ele_num) as sum from global_temp.cdz where ele_num > 100 group by id")
newResDF.printSchema()
newResDF.show()
newSS.stop()
}