2014-02-17 2 views
1

ПРЕДПОСЫЛКА: Я немного использовал MDX, но я никоим образом не специалист по этому вопросу - ища некоторую помощь в выполнении. Я работаю над набором рассчитанных мер (Number of Stores Authorized/In-Stock/Selling/Etc) (MDX) в кубе SQL Server Analysis Services 2012 Cube. У меня были эти вычисления, выполненные хорошо изначально, но обнаружили, что они не агрегируются по моей иерархии продуктов так, как я их нуждался. В этом отчете используются две иерархии: Бизнес -> Предмет и Отдел -> Магазин.MDX - Количество фильтров CROSSJOIN - Проблемы с производительностью

Например, в исходном калькуляторе MDX показатель «Магазины на складе» будет корректно работать на уровне «Товар», но не будет свертывать правильную сумму на уровне «Бизнес» над ним. На уровне бизнеса мы хотим видеть общее количество комбинаций магазинов/продуктов в запасе, а не отличное или MAX-значение, как это, казалось, изначально.

Подлинные ЗАПРОСА РЕЗУЛЬТАТЫ: Вот пример этого НЕ работают правильно (представьте себе это сводная таблица Excel):

[FILTER: CURRENT WEEK DAYS] 
[BUSINESS]   [AUTH. STORES] [STORES IN-STOCK] [% OF STORES IN STOCK] 
[+] Business One 2,416   2,392    99.01% 
[-] Business Two 2,377   2,108    93.39% 
    -Item 1   2,242   2,094    99.43% 
    -Item 2   2,234   1,878    84.06% 
    -Item 3   2,377   2,108    88.68% 
    -Item N   ...    ...     ... 

FIXED ЗАПРОС РЕЗУЛЬТАТЫ: После долгих проб и ошибок, я переключился на использование фильтрованного счета CROSSJOIN() двух иерархий, используя функцию DESCENDANTS(), которая привела к правильным номерам (ниже):

[FILTER: CURRENT WEEK DAYS] 
[BUSINESS]   [AUTH. STORES] [STORES IN-STOCK] [% OF STORES IN STOCK] 
[+] Business One 215,644   149,301    93.90% 
[-] Business Two 86,898   55,532    83.02% 
    -Item 1   2,242   2,094    99.43% 
    -Item 2   2,234   1,878    99.31% 
    -Item 3   2,377   2,108    99.11% 
    -Item N   ...    ...     ... 

QUERY ЧТО НУЖНА ПОМОЩЬ: Вот это «новый» запрос, который дает результаты выше:

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock] 
AS COUNT(
    FILTER(
     CROSSJOIN(
      DESCENDANTS(
       [Product].[Item].CURRENTMEMBER, 
       [Product].[Item].[UPC]   
      ), 
      DESCENDANTS(
       [Division].[Store].CURRENTMEMBER, 
       [Division].[Store].[Store ID]  
      ) 
     ), 
     [Measures].[Inventory Qty] > 0 
    ) 
), 
FORMAT_STRING = "#,#", 
NON_EMPTY_BEHAVIOR = { [Inventory Qty] }, 

Этот синтаксис запроса используется в кучу других «Количество магазинов Продажа/Нет на складе/Etc . "- тип вычисляемых измерений в кубе, только с изменением состояния [Инвентарный Кол-во] внизу или путем объединения дополнительных условий.

В текущем состоянии этот запрос может занять 2-3 минуты, что слишком долго для аудитории этой отчетности. Может ли кто-нибудь подумать о способе уменьшить нагрузку на запрос или помочь мне переписать это, чтобы быть более эффективным?

Спасибо!


UPDATE 2/24/2014: Мы решили эту проблему, минуя множество многомерных выражений, участвующих и добавление значения флагов нашего имени запрос в DSV.

Например, вместо того, чтобы делать команду фильтра в коде MDX для «количества магазинов, продающих» - мы просто добавили это к таблице фактов с именем запрос ...

CASE WHEN [Sales Qty] > 0 
    THEN 1 
    ELSE NULL 
END AS [Flag_Selling] 

... тогда мы просто агрегировали эти меры как LastNonEmpty в кубе. Они работают быстрее, чем запросы MDX.

ответ

1

Это должно быть гораздо быстрее моделировать условия в куб, избегая медленно Filter функцию:

Если есть только несколько условий, добавить атрибут для каждого из них с двумя значениями, одно для условия выполнил, скажет «cond: yes», а один для условия не выполнен, скажем «cond: no». Вы можете определить это в представлении таблицы физического факта или в DSV, или вы можете моделировать его физически.Эти атрибуты могут быть добавлены непосредственно в таблицу фактов, определяя измерение в одной и той же таблице или более чисто, как отдельную таблицу измерений, ссылающуюся на таблицу фактов. Затем определите свою меру как

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock] 
AS COUNT(
    CROSSJOIN(
     DESCENDANTS(
      [Product].[Item].CURRENTMEMBER, 
      [Product].[Item].[UPC]   
     ), 
     DESCENDANTS(
      [Division].[Store].CURRENTMEMBER, 
      [Division].[Store].[Store ID]  
     ), 
     { [Flag dim].[cond].[cond: yes] } 

    ) 
) 

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

В случае, когда существует много условий, имеет смысл добавить только один атрибут с одним значением для каждого условия в качестве отношения «многие ко многим». Это будет немного медленнее, но все же быстрее, чем звонок Filter.

+0

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

+0

Мы пошли дальше и смоделировали условия в кубе, как вы рекомендовали, и он работает примерно в 5 раз быстрее. Полагаю, мы пытались получить слишком много внимания с MDX! –

1

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

CREATE MEMBER CURRENTCUBE.[Measures].[Num Stores In-Stock] 
AS 
CASE WHEN [Product].[Item Name].CURRENTMEMBER IS [Product].[Item Name].[All] 
THEN 
SUM(EXISTS([Product].[Item Name].[Item Name].MEMBERS,[Business].[Business Name].CURRENTMEMBER), 
COUNT(
EXISTS(
    [Division].[Store].[Store].MEMBERS, 
    (
     [Business].[Business Name].CURRENTMEMBER, 
     [Product].[Item Name].CURRENTMEMBER 
    ), 
    "Measure Group Name" 
) 
)) 
ELSE 
COUNT(
EXISTS(
    [Division].[Store].[Store].MEMBERS, 
    (
     [Business].[Business Name].CURRENTMEMBER, 
     [Product].[Item Name].CURRENTMEMBER 
    ), 
    "Measure Group Name" 
) 
) 
END 

Я попробовал, используя измерение в моем кубе и используя Area-Дочернее иерархии. В заявлении case обрабатывается ситуация просмотра данных на уровне Business. В основном, SUM() для всех членов наименований элементов, используемых в операторе CASE, вычисляет значения для отдельных имен элементов, а затем суммирует все значения. Я считаю, что это то, что вам нужно.

Смежные вопросы