web-dev-qa-db-ja.com

Spark SQL:rdd.cache()を使用せずにSQLクエリ結果をキャッシュする方法

Rdd.cache()を使用せずにキャッシュSQLクエリ結果をキャッシュする方法はありますか?例えば:

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

output.cache()を使用して結果をキャッシュできますが、SQLクエリを使用して結果を処理することはできません。

結果をキャッシュするためにsqlcontext.cacheTable()のようなものはありますか?

13
lwwwzh

キャッシュするにはsqlContext.cacheTable("table_name")を使用するか、CACHE TABLE table_name SQLクエリを使用する必要があります。

ここに例があります。私はこのファイルをHDFSに持っています:

1|Alex|[email protected]
2|Paul|[email protected]
3|John|[email protected]

次に、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')

これでテーブルが作成され、クエリを実行できます。

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()     

1番目と2番目のオプションは、最適化されたメモリ内の列形式でデータをキャッシュするので、3番目のオプションは、他のRDDと同じように行指向の方法でキャッシュします。

だからあなたの質問に戻って、ここに1つの可能な解決策があります:

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

以下は、RDDに.cacheを使用する場合に最も似ており、Zeppelinまたは同様のSQL-heavy-environmentsで役立ちます。

_CACHE TABLE CACHED_TABLE AS
SELECT $interesting_query
_

次に、_interesting_query_の後続の使用と、_CACHED_TABLE_に対するすべてのクエリの両方で、キャッシュされた読み取りを取得します。

この回答は受け入れられた回答に基づいていますが、ASを使用することで、.collect()またはRDDを実行できない、より制約の多いSQLのみの環境で呼び出しが実際に役立つようになりました/ Dataframe-operations。

8
Rick Moritz