Spark SQL:如何在不使用 rdd.cache() 的情况下缓存 sql 查询结果

Spark SQL: how to cache sql query result without using rdd.cache()

有没有什么方法可以在不使用 rdd.cache() 的情况下缓存缓存 sql 查询结果? 例如:

output = sqlContext.sql("SELECT * From people")

我们可以使用output.cache()来缓存结果,但是之后就不能使用sql查询来处理了。

所以我想问一下有没有类似sqlcontext.cacheTable()的缓存结果?

您应该使用 sqlContext.cacheTable("table_name") 来缓存它,或者使用 CACHE TABLE table_name SQL 查询。

这是一个例子。我在 HDFS 上有这个文件:

1|Alex|alex@gmail.com
2|Paul|paul@example.com
3|John|john@yahoo.com

然后PySpark中的代码:

people = sc.textFile('hdfs://sparkdemo:8020/people.txt')
people_t = people.map(lambda x: x.split('|')).map(lambda x: Row(id=x[0], name=x[1], email=x[2]))
tbl = sqlContext.inferSchema(people_t)
tbl.registerTempTable('people')

现在我们有一个table并且可以查询它:

sqlContext.sql('select * from people').collect()

要坚持下去,我们有 3 个选择:

# 1st - using SQL
sqlContext.sql('CACHE TABLE people').collect()
# 2nd - using SQLContext
sqlContext.cacheTable('people')
sqlContext.sql('select count(*) from people').collect()     
# 3rd - using Spark cache underlying RDD
tbl.cache()
sqlContext.sql('select count(*) from people').collect()     

首选第一个和第二个选项,因为它们将以优化的内存中列格式缓存数据,而第三个选项将像任何其他 RDD 一样以面向行的方式缓存数据

所以回到你的问题,这是一种可能的解决方案:

output = sqlContext.sql("SELECT * From people")
output.registerTempTable('people2')
sqlContext.cacheTable('people2')
sqlContext.sql("SELECT count(*) From people2").collect()

以下最像是将 .cache 用于 RDD,对 Zeppelin 或类似的工具很有用 SQL-heavy-environments

CACHE TABLE CACHED_TABLE AS
SELECT $interesting_query

然后您将获得 interesting_query 后续使用以及 CACHED_TABLE.

上所有查询的缓存读取

这个答案是基于已接受的答案,但是使用 AS 的力量真正使调用在更受限制的 SQL-only 环境中有用,在这些环境中你不能 .collect() 或以任何方式做 RDD/Dataframe-operations。