Прямой запрос файла против запроса фрейма данных после чтения файла - PullRequest
0 голосов
/ 27 сентября 2018

Метод 1: Запрос файла паркета напрямую как:

val sqlDF = spark.sql("SELECT columns FROM parquet.`sample.parquet`")

и

Метод 2: Запрос кадра данных после чтения файла паркета как:

df = spark.read.parquet(path_to_parquet_file)
df.select(columns)

и

Метод 3: Запрос временного представления как:

df.createOrReplaceTempView("sample")
val sqlDF = spark.sql("SELECT columns FROM sample")
  1. За сценой все 3 по существу выполняются одинаково?
  2. В методе1, перед преобразованием запроса паркет преобразуется в набор данных / набор данных?
  3. Какой из 3 методов эффективен и почему?(если они разные)
  4. Есть ли конкретный вариант использования для этих методов?(если они разные)

Спасибо!

Ответы [ 2 ]

0 голосов
/ 27 сентября 2018

Если вы пытаетесь оценить, какие 3 из них лучше подходят для той же цели, между ними нет никакой разницы.physical plan ответьте на ваш вопрос: «За сценой?».

Метод 1:

sqlDF = spark.sql("SELECT CallNumber,CallFinalDisposition FROM parquet.`/tmp/ParquetA`").show()

== Physical Plan ==
CollectLimit 21
+- *(1) Project [cast(CallNumber#2988 as string) AS CallNumber#3026, CallFinalDisposition#2992]
   +- *(1) FileScan parquet [CallNumber#2988,CallFinalDisposition#2992] Batched: true, Format: Parquet, Location: InMemoryFileIndex[dbfs:/tmp/ParquetA], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<CallNumber:int,CallFinalDisposition:string>

Метод 2:

df = spark.read.parquet('/tmp/ParquetA')
df.select("CallNumber","CallFinalDisposition").show()

== Physical Plan ==
CollectLimit 21
+- *(1) Project [cast(CallNumber#3100 as string) AS CallNumber#3172, CallFinalDisposition#3104]
   +- *(1) FileScan parquet [CallNumber#3100,CallFinalDisposition#3104] Batched: true, Format: Parquet, Location: InMemoryFileIndex[dbfs:/tmp/ParquetA], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<CallNumber:int,CallFinalDisposition:string>

Метод 3:

tempDF = spark.read.parquet('/tmp/ParquetA/')
tempDF.createOrReplaceTempView("temptable");
tiny = spark.sql("SELECT CallNumber,CallFinalDisposition FROM temptable").show()

== Physical Plan ==
CollectLimit 21
+- *(1) Project [cast(CallNumber#2910 as string) AS CallNumber#2982, CallFinalDisposition#2914]
   +- *(1) FileScan parquet [CallNumber#2910,CallFinalDisposition#2914] Batched: true, Format: Parquet, Location: InMemoryFileIndex[dbfs:/tmp/ParquetA], PartitionFilters: [], PushedFilters: [], ReadSchema: struct<CallNumber:int,CallFinalDisposition:string>
0 голосов
/ 27 сентября 2018

Короткий ответ

Да.3 способа, которыми вы иллюстрировали запрос файла Parquet с использованием Spark, выполняются одинаково.

Длинный ответ

Причина, по которой это так, заключается в комбинациидве особенности Spark: отложенная оценка & оптимизация запросов .

Как разработчик, вы можете разделить операции Spark на несколько этапов (как вы это делали в методе 2).).Внутри Spark (лениво) оценивает операции в сочетании и применяет к ним оптимизацию.В этом случае Spark может оптимизировать операции путем сокращения столбцов (в основном, он не будет считывать все данные паркета в память; только конкретные столбцы, которые вы запросили.)

Третий метод создания временного представления -просто присвоить имена прочитанным данным, чтобы вы могли ссылаться на них в дальнейших операциях.Во-первых, это не меняет способа его вычисления.

Для получения дополнительной информации об оптимизации, выполненной Spark при чтении паркета, см. Эту подробную статью .

ПРИМЕЧАНИЕ: Как я уже упоминал в комментарии к вопросу, вы выбрали определенные столбцы в методе 2;в то время как два других считывают все данные.Так как это принципиально разные операции, будет разница в исполнении.Приведенный выше ответ предполагает, что аналогичные операции выполнялись в каждом из трех методов (либо чтение полных данных, либо некоторые конкретные столбцы из файла).

...