Power BI / Query избегает материализации результатов объединения до GROUP BY - PullRequest
1 голос
/ 30 января 2020

Цель

Я использую Power BI Desktop, кластер DirectQuery для Spark. Я хочу объединить две таблицы и агрегировать по столбцам MONTH и DEP_NAME. Таблица фактов имеет размер 10 ГБ + (содержит столбец MONTH), а таблица Department - около нескольких КБ (содержит столбцы DEP_ID, DEP_NAME). Ожидаемый результат очень маленький, около 100 строк.

Проблема

Ошибка искры из-за следующего исключения:

DataSource.Error: ODB C: ОШИБКА [HY000] [Microsoft] [Hardy] ( 35) Ошибка сервера: код ошибки: «0». Сообщение об ошибке: «Ошибка выполнения запроса: org. apache .spark.SparkException: задание прервано из-за сбоя этапа: общий размер сериализованных результатов для 10 заданий (4,1 ГБ) равен больше, чем spark.driver.maxResultSize (4,0 ГБ) '.

Я почти уверен, что Power BI пытается материализовать результат объединения (10 ГБ +) перед применением агрегирования.

Вопрос

Есть ли способ заставить Power BI не выполнять / не выполнять результаты объединения без применения агрегирования?

Power Query

let
    Source = ApacheSpark.Tables("https://xxxxxxxxx.azuredatabricks.net:443/sql/protocolv1/o/yyyyyyyyyyy", 2, [BatchSize=null]),
    #"Result" = Table.Group(
        Table.Join(
            Source{[Schema="default",Item="Fact"]}[Data], 
            "DEP_ID", 
            Table.RenameColumns(Source{[Schema="default",Item="Department"]}[Data], {"DEP_ID", "DEP_ID_"}), 
            "DEP_ID_", 
            JoinKind.Inner
        ), 
        {"MONTH", "DEP_NAME"}, 
        {{"TOTAL_SALARY", each List.Sum([SALARY]), type number}}
    )
in
    #"Result"

Power Query не удалось план выполнения задания

Из Spark SQL плана выполнения вы можете видеть, что нет этапа агрегации, только присоединение! Я думаю, что Power BI пытается загрузить результаты объединения (10 ГБ +) через Spark Driver перед применением агрегирования GROUP BY.

enter image description here

Ожидаемый план выполнения

Я могу написать ту же работу с PySpark:

dep = spark.read.csv(dep_path)
spark.read.parquet(fact_pat) \
    .join(F.broadcast(dep), ['DEP_ID']) \
    .groupBy('MONTH', 'DEP_NAME') \
    .agg(F.sum('SALARY')) \
    .show(1000)

План будет следующим (обратите внимание на ha sh совокупных шагов в конце):

enter image description here

PS

AFAIK, Power BI Desktop "Просмотр собственного запроса" отключен для Spark DirectQuery.

UPD

Похоже на проблема не в сворачивании запросов, Power BI по какой-то причине материализует таблицу до GROUP BY даже без объединения. Следующий запрос приводит к полной загрузке таблицы:

let
    Source = ApacheSpark.Tables("https://xxxxxxxx.azuredatabricks.net:443/sql/protocolv1/o/yyyyyyyyyyyy", 2, [BatchSize=null]),
    #"Result" = Table.Group(
        Source{[Schema="default",Item="Fact"]}[Data],
        {"MONTH", "DEP_ID"}, 
        {{"TOTAL_SALARY", each List.Sum([SALARY]), type number}}
    )
in
    #"Result"

Тем не менее, полная загрузка происходит только в случае функции List.Sum. List.Count и List.Max работают хорошо, даже с объединением таблиц до GROUP BY.

1 Ответ

2 голосов
/ 30 января 2020

Вместо того, чтобы объединяться, а затем группировать, возможно, вы могли бы сделать наоборот. Сгруппируйте по MONTH и DEP_ID из таблицы Fact, а затем объедините с таблицей Department, чтобы получить DEP_NAME.

Примечание. Если несколько DEP_ID имеют одинаковые DEP_NAME , вам нужно будет создать еще одну группу после присоединения.

...