2016-09-23 2 views
11

이전에는 다양한 R 스크립트의 데이터를 가져 오는 데 사용되었던 여러 SQL 쿼리를 코딩하는 데 꽤 많은 시간을 보냈습니다. 이 문제를 해결하지 않는 데이터베이스 자체에 VIEW의를 만드는 이유 - 이것은 이전 쿼리의 결과가 필요한 일부 쿼리에 대한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) 

을 통해 그냥 할 수있는 방법을 알아 냈하지만이 내 소견에 매우 가로장 설치 등등입니다. 또한보다 복잡한 검색어 (예 : 부질의 인자를 incooporate하는 쿼리는 현재 작동하지 않습니다. 같은보다 강력한 방법이 재 구현 등 .select($""), filter($"") 사용 Spark.SQL 코드로 SQL 코드를

전반적인 목표는 하나 개 이전 SQL 쿼리의 결과를 나타내는 각 (여러 org.apache.spark.sql.DataFrame의를 얻는 것입니다

하는 항상 약간 JOINs, WITHs 등). 따라서 nDataFrame으로 연결되는 검색어는 n입니다.

제공된 두 개보다 더 좋은 옵션이 있습니까?

설정 : 하둡 v.2.7.3, 2.0.0, 인텔리 J의 IDEA 2016.2를, 스파크 스칼라 2.11.8는 Testcluster는 Win7에 워크 스테이션에

+0

전 충분히 이해하지 못했습니다. 단일 sql 파일에 여러 개의 쿼리가 있고 각 쿼리를 마지막에 TempView로 등록하려면? 또는 각각 하나의 쿼리와 각 쿼리가 하나의 TempView를 등록하는 여러 개의 sql 파일? 질문에 문제가 보이지 않습니다. –

+0

후자, 감사합니다! 나는 그것을 명확하게하기 위해 몇 가지 정보를 추가했다. – Boern

+0

좋아, 그래서 당신 n 데이터 파일에서 n DataFrames 싶어요. 이미 추가 한 코드에서 해결되었습니다. 솔루션에서 "피들 (fiddly)"이란 무엇이며, 왜 "더 나은"솔루션이 필요합니까? 대답은 무엇을 최적화해야합니까? –

답변

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에서는 이러한 테이블을 Materialized Views라고 부릅니다. 즉 뷰와 같은 다른 데이터에 대한 변환이지만 이후의 재사용을 위해 결과가 캐시됩니다.

관련 문제