Эффективное чтение / преобразование секционированных данных в дельта-озере

У меня есть данные в дельте озера в ADLS, и я читаю их через Databricks. Данные разделены по году и дате, а z упорядочены по storeIdNum, где имеется около 10 идентификаторов магазинов, каждый из которых содержит несколько миллионов строк на дату. Когда я его читаю, иногда я читаю один раздел даты (~ 20 миллионов строк), а иногда я читаю данные за целый месяц или год, чтобы выполнить пакетную операцию. У меня есть вторая гораздо меньшая таблица с примерно 75000 строк на дату, которая также z упорядочена storeIdNum, и большинство моих операций включают присоединение большей таблицы данных к меньшей таблице на storeIdNum (и некоторых других полях - например, временном окне , меньшая таблица сводится по часам, а другая таблица содержит точки данных каждую секунду). Когда я читаю таблицы, я присоединяюсь к ним и выполняю кучу операций (группировка, окно и разделение с помощью функций lag / lead / avg / density_rank и т. Д.).

У меня такой вопрос: должна ли я указывать дату во всех операторах объединения, группировки и разделения? Каждый раз, когда я читаю одну дату данных, у меня всегда есть год и дата в операторе, который читает данные, поскольку я знаю, что я хочу читать только из определенного раздела (или года разделов), но важно также ссылаться на раздел col. в окнах и групповой шине для повышения эффективности, или это избыточно? После анализа / преобразований я не собираюсь перезаписывать / изменять данные, которые я читаю, а вместо этого записываю в новую таблицу (вероятно, разделенную на те же столбцы), если это является фактором.

Например:

dfBig = spark.sql("SELECT YEAR, DATE, STORE_ID_NUM, UNIX_TS, BARCODE, CUSTNUM, .... FROM STORE_DATA_SECONDS WHERE YEAR = 2020 and DATE='2020-11-12'")
dfSmall = spark.sql("SELECT YEAR, DATE, STORE_ID_NUM, TS_HR, CUSTNUM, .... FROM STORE_DATA_HRS WHERE YEAR = 2020 and DATE='2020-11-12'")

Теперь, если я присоединюсь к ним, хочу ли я включить YEAR и DATE в соединение, или я должен просто присоединиться к STORE_ID_NUM (а затем к любому из полей метки времени / номера идентификатора клиента, к которому мне нужно присоединиться)? Мне определенно нужен STORE_ID_NUM, но я могу отказаться от ГОДА И ДАТЫ, если он просто добавляет еще один столбец и делает его более неэффективным, потому что это больше вещей, к которым можно присоединиться. Я не знаю, как именно это работает, поэтому я хотел проверить, отказавшись от соединения, возможно, я делаю его более неэффективным, поскольку не использую разделы при выполнении операций? Спасибо!


person WIT    schedule 13.11.2020    source источник


Ответы (1)


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

В вашем случае я считаю целесообразным разделить по ГОДУ, но я бы добавил МЕСЯЦ с учетом количества записей, которые несколько помогли бы с динамической обрезкой искры

Еще вы можете попробовать использовать BRADCAST JOIN, если таблица очень мала по сравнению с другой.

Broadcast Hash Join en Spark (ES)

Подсказки по стратегии присоединения для SQL-запросы

Последняя ссылка объясняет, как динамическое сокращение помогает в операциях MERGE.

Как повысить производительность запросов Delta Lake MERGE INTO с помощью сокращения разделов

person Cristián Vargas Acevedo    schedule 12.01.2021