Помогает ли секционирование при чтении ключевых столбцов с помощью функции?

У меня есть этот фрейм данных:

+------+
|my_col|
+------+
|202101|
|202209|
+------+

При записи в виде файла паркета я разделяю его на основе столбца «my_col», поэтому у меня должно получиться два раздела (два файла паркета).

Затем я буду читать сохраненный набор данных, применяя фильтр.

  1. Я правильно понимаю, что Spark не будет загружать данные в память из файла, содержащего my_col=202101, при применении фильтра .filter("my_col >= 202201")?
  2. Будут ли данные из файла паркета, содержащего my_col=202101, загружаться в память при применении фильтра .filter("substring(my_col, 1, 4) >= 2022")?

В последнем случае я не фильтрую напрямую значения ключевого столбца, а вместо этого к столбцу применяется функция. Интересно, поможет ли в этом случае разбиение на разделы сэкономить время чтения.

Ты можешь объяснить

thebluephantom 02.06.2024 22:08

не заслуживает отдельного ответа (Ахмеду), но это верно только для обрезки разделов, где искра эффективно выполняет его, когда он отключен на уровне поля (предикаты нажатия/PushedFilters) разрешено только простое равенство /in, функции - нет . Это привело к пользовательской оптимизации качества, чтобы избежать «сканирования таблиц».

Chris 03.06.2024 10:52

В зависимости от версии Spark и хранилища метаданных вы можете увидеть разницу в том, какие предикаты передаются для оценки в хранилище метаданных, и то, что Spark должен фильтровать на стороне клиента. См. Issues.apache.org/jira/plugins/servlet/mobile#issue/SPARK-33‌​537

mazaneicha 04.06.2024 13:28
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
107
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поэтому я попробовал приведенный ниже пример, чтобы выяснить, имеет ли какое-либо значение функция, используемая в фильтре. Пример:

data = [
    ("A ", "202201"),
    ("B ", "202209"),
    ("C ", "202210"),
    ("D ", "202301"),
]

columns = ["name", "dob"]
df = spark.createDataFrame(data, columns)

df.write.partitionBy("dob").mode("overwrite").parquet("people.parquet")

people = spark.read.parquet("people.parquet")
people_filtered_without_function = people.filter("dob >= 202201")
people_filtered_with_function = people.filter("substring(dob, 1, 4) >= 2022")

people_filtered_without_function.explain()
people_filtered_with_function.explain()

Вот результаты физических планов:

  1. Без функции

== Физический план == *(1) СтолбецToRow +- FileScan паркет [имя#7,доб#8] Пакетный: true, DataFilters: [], Формат: Паркет, Расположение: InMemoryFileIndex(1 путь)[файл:/opt/spark/work-dir/people.parquet], PartitionFilters: [isnotnull(dob#8), (dob#8 >= 202201)], PushedFilters: [], ReadSchema: structname:string

  1. С функцией

== Физический план == *(1) СтолбецToRow +- FileScan паркет [имя#7,доб#8] Пакетный: true, DataFilters: [], Формат: Паркет, Расположение: InMemoryFileIndex(1 путь)[файл:/opt/spark/work-dir/people.parquet], PartitionFilters: [isnotnull(dob#8), (cast(substring(cast(dob#8 as string), 1, 4) as int) >= 2022)], PushedFilters: [], ReadSchema: structname:string

Обратите внимание, что основное отличие заключается в следующем:

Фильтр разделов (без):

(доб#8 >= 202201)

Фильтр разделов (с):

(cast(substring(cast(dob#8 as string), 1, 4) as int) >= 2022)

Как вы можете видеть выше, разницу между этими двумя методами. Я бы сказал, что происходит вот что:

  • Да, действительно данные будут фильтроваться спарком и считываться только соответствующие файлы.
  • План также отражает использование функций в фильтре. Поэтому я бы предположил, что основным отличием в производительности здесь являются только накладные расходы на приведение типов и применение функций, а не фактическая логика фильтрации.

Хорошо, я не знал о PartitionFilters внутренних планах запросов. Спасибо! Похоже, что разделение по столбцу dob стоит того, даже если последующие фильтры чтения используют (базовые) функции.

ZygD 03.06.2024 13:05

Другие вопросы по теме