Есть ли разница в чтении набора данных spark с использованием фильтра по сравнению с базовым путем полный путь фильтра?

#apache-spark #partitioning

#apache-spark #разделение

Вопрос:

Что касается эффективности чтения набора данных, разделенного некоторым столбцом, есть ли разница между:

 // (1) read all dataset then filter
spark.read.parquet("/root/path").filter(col("mycolumn") === 42)
  

и

 // (2) read directly the required data subset
spark.read.option("basePath", "/root/path").parquet("/root/path/mycolumn=42")
  

?

Я спрашиваю об этом в контексте, когда файлы данных не хранятся в том же кластере, что и spark (поэтому нет местоположения данных). И мне интересно, в частности, если в случае (1) он будет извлекать полные файлы набора данных в кластере spark, затем фильтровать его (надеюсь, без фактического чтения файлов), или если фильтр действительно будет выполнен до извлечения файла, чего я ожидаю от случая (2)сделайте.

Ответ №1:

разница огромная.

В первом случае вы будете читать весь файл, а затем фильтровать, во втором случае вы будете читать только выбранный файл (фильтрация уже выполнена разделением).

вы можете проверить, является ли фильтр предикатом pushdown, используя explain() function . В вашем FileScan parquet вы увидите PushedFilters и PartitionFilters

в вашем случае вы должны прочитать разделенные данные без фильтра.

 spark.read.option("basePath", "/root/path").parquet("/root/path/mycolumn=42")
  

Комментарии:

1. Это то, чего я ожидал тогда (и боялся, потому что мне нужно требовать смены хранилища от других людей …). Spark не выводит PartitionFilter из a .filter() в столбце раздела: (

2. Я изучил это, и у меня есть вопрос: может быть, я не правильно понимаю, что такое предикатный pushdown filter, но: если использовать фильтр (т.Е. Метод 2), добавляет PartitionFilter в планы, это почти не то же самое, что использовать метод (1) с базовым путем? Т.е. При загрузкеданные, он увидит, что ‘mycolumn’ является столбцом раздела, и, следовательно, фильтрует непосредственно по пути к файлу?