Нужна помощь в оптимизации многоуровневого сводного расчета DAX.

Мне нужен совет о том, как оптимизировать многоуровневый запрос сводки DAX. Этот очень медленный, потому что, я думаю, он работает O (n ^ 3) из-за вложенности. К сожалению, мне нужно иметь несколько уровней, потому что уровни иерархии Заказ > Строка заказа > Детали заказа должны рассчитываться по-разному.

  • Единицы должны суммироваться до уровня детализации
  • Это должно быть усреднено до уровня Line
  • Это нужно подвести к уровню Ордена

    SUMX(
        SUMMARIZE(
             'FACT Opportunity'
            ,Opportunity[LineId]
            ,"Units"
            ,AVERAGEX(
                SUMMARIZE(
                    'FACT Opportunity'
                    ,Opportunity[DetailId]
                    ,"SumDetail"
                    ,SUM('FACT Opportunity'[Units])
                    )
                ,[SumDetail]
                )
        )
        ,[Units]
    )
    

    Любая помощь или совет, который вы могли бы предоставить, будут очень признательны.


person Stephen Re    schedule 12.10.2018    source источник


Ответы (1)


Очень сложно дать совет по оптимизации, не видя данных и модели данных (было бы здорово, если бы они были включены в вопрос).

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

Очевидное решение состоит в том, чтобы сделать «Единицы» полностью аддитивными. Вы можете вычислить дедуплицированные (с поправкой на дубликаты) единицы и сохранить их в фактических возможностях в виде вычисляемого столбца:

Adjusted  Units =
DIVIDE (
    'FACT Opportunity'[Units],
    CALCULATE ( COUNT ( 'FACT Opportunity'[DetailId] ) )
)

Здесь вы делите единицы на количество уникальных DetailID (обычно это будет 1, но в случае повторяющихся DetailID будет 2 и т. д.).

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

Скорректированные единицы являются полностью аддитивными, поэтому теперь вы можете просто:

Total Units = SUM('FACT Opportunity'[Adjusted Units])

Он должен корректно работать на любом уровне иерархии Order > Line > Detail (если нет дополнительных проблем, не описанных в вопросе), и он должен быть быстрым.

person RADO    schedule 12.10.2018