2016-09-23 14 views
11

以前はさまざまなRスクリプトのデータを取得するために使用されていた複数のSQLクエリをコード化するのにかなりの時間を費やしました。なぜデータベース自体にVIEW Sを作成すると、この問題が解決しない - これは、手がかりがいくつかのクエリのために前のクエリからの結果が必要であること、であるScala&Spark:リサイクルSQLステートメント

sqlContent = readSQLFile("file1.sql") 
sqlContent = setSQLVariables(sqlContent, variables) 
results = executeSQL(sqlContent) 

を働いていた方法です。 Spark 2.0で、私はすでに

// create a dataframe using a jdbc connection to the database 
val tableDf = spark.read.jdbc(...) 
var tempTableName = "TEMP_TABLE" + java.util.UUID.randomUUID.toString.replace("-", "").toUpperCase 
var sqlQuery = Source.fromURL(getClass.getResource("/sql/" + sqlFileName)).mkString 
sqlQuery = setSQLVariables(sqlQuery, sqlVariables) 
sqlQuery = sqlQuery.replace("OLD_TABLE_NAME",tempTableName) 
tableDf.createOrReplaceTempView(tempTableName) 
var data = spark.sql(sqlQuery) 

てちょうどそれを行う方法を考え出したしかし、これは私の謙虚な意見では非常に手間のかかるです。さらに複雑なクエリ(例:サブクエリの因数分解を非同期化するクエリは現在動作しません。

は、(全体的な目標がそれぞれ1つの前のSQLクエリの結果を表す、複数のorg.apache.spark.sql.DataFrame Sを取得することです

など、filter($"")を使用してSpark.SQLコードに再実装SQLコードのような、より堅牢な方法は、あります.select($"")常にいくつかのJOINs、WITHsなど)。したがってnDataFrameにつながるクエリn

2つのオプションよりも優れたオプションがありますか?

セットアップ:Hadoopのv.2.7.32.0.0スパーク、インテリJのIDEA 2016.2は、Scalaの2.11.8は、TestclusterはWin7のワークステーション

+0

私は完全にそれを得ていませんでした。単一のSQLファイルに複数のクエリがあり、最後に各クエリをTempViewとして登録する必要がありますか?または複数のsqlファイル、それぞれが1つのクエリを持ち、各クエリが1つのTempViewを登録していますか?私は問題の問題を見ない。 –

+0

後者、ありがとう!私はそれを明確にするためにいくつかの情報を追加しました。 – Boern

+0

だから、n個のsqlファイルからn個のDataFramesが必要です。あなたが追加したコードですでに解決されています。あなたのソリューションの中で "偽装"とは何か、なぜあなたは "より良い"ソリューションを必要としますか? –

答えて

1

にそれはあなたの要件が何であるか、特に明確ではないのですが、私はあなたがクエリにのようなものを持って言っていると思います:

SELECT * FROM people LEFT OUTER JOIN places ON ... 
SELECT * FROM (SELECT * FROM people LEFT OUTER JOIN places ON ...) WHERE age>20 

、あなたが宣言し

SELECT * FROM people LEFT OUTER JOIN places ON ... 
SELECT * FROM <cachedresult> WHERE age>20 
として効率的にこれを実行したいと思います

これを達成するために、入力ファイルを拡張して、各SQL文に結果が格納される関連するテーブル名を持たせるようにします。

その後

PEOPLEPLACES\tSELECT * FROM people LEFT OUTER JOIN places ON ... 
ADULTS=SELECT * FROM PEOPLEPLACES WHERE age>18 

ので、必要なすべてのテーブルが作成されているために、あなたはクエリを宣言していることを確認してください

parseSqlFile().foreach({case (name, query) => { 
    val data: DataFrame = execute(query) 
    data.createOrReplaceTempView(name) 
} 

のようなループで実行されます。他のものはもう少し構文解析し、依存関係によって並べ替えます。

RDMSでは、これらのテーブルをマテリアライズドビューと呼びます。すなわち、ビューのような他のデータへの変換であり、後の再利用のために結果をキャッシュする。

関連する問題