Saturday, February 25, 2012

MDX queries from Reporting Services

I have been having some issues with generating reports in Reporting

Services off Analysis Services, in that the reports take a very long

time and I have to often kill the queries. They are using 100%CPU. I have then replicated as

closely as possible the report using the Cube Analysis add in for

Excel, and the response is almost instantaneous.

It

seems it is the MDX that Reporting Services is very inefficient

compared to that generated by Cube Analysis. It uses Selects in the From clause to restrict the scope of the query using the Filter parameters. Is this something anyone has come across, and are there any suggestions to get round it? I did try

to paste the Cube Analysis MDX into Reporting Services but the parser

rejected it as invalid.

I attach the comparitive MDX below for reference

Cube Analysis
SELECT

NON EMPTY{Hierarchize({CROSSJOIN({CROSSJOIN({{{[Portfolio].[Benchmark

Portfolio].[All],[Portfolio].[Benchmark Portfolio].[All].children} +

{{[Portfolio].[Benchmark

Portfolio].[Benchmark].&[1].children}}}},{{[Scenario].[Scenario].&[1],[Scenario].[Scenario].&[1].children}

+

{[Scenario].[Scenario].&[3],[Scenario].[Scenario].&[3].children}

+

{[Scenario].[Scenario].[Benchmark],[Scenario].[Scenario].[Benchmark].children}

+ {[Scenario].[Scenario].[Variance to

Benchmark],[Scenario].[Scenario].[Variance to

Benchmark].children}})},{{[Measures].[Duration]} +

{[Measures].[Weighting]}})})} on 0, NON

EMPTY{Hierarchize({{[Sector].[Sector Category].[All],[Sector].[Sector

Category].[All].children}})} on 1 from [MIQB27] where

([Period].[Year-

Month].[Month].&[2006-03-01T00:00:00],[Benchmark].[Benchmark].&[1],[Rating].[Rating

Category].[All],[Currency of Exposure].[Currency].&[2]) CELL

PROPERTIES VALUE, FORMATTED_VALUE, FONT_NAME, FONT_SIZE,

FONT_FLAGS,FORE_COLOR, BACK_COLOR, FORMAT_STRING

Reporting Services

SELECT NON EMPTY

{ [Measures].[Duration], [Measures].[Weighting] } ON

COLUMNS, NON EMPTY { ([Sector].[Sector Category].[Sector

Category].ALLMEMBERS *

[Benchmark].[Benchmark].[Benchmark].ALLMEMBERS

* [Portfolio].[Portfolio].[Portfolio].ALLMEMBERS

* [Scenario].[Scenario].[Scenario].ALLMEMBERS

) } DIMENSION PROPERTIES

MEMBER_CAPTION, MEMBER_UNIQUE_NAME

ON ROWS FROM ( SELECT ( {

[Scenario].[Scenario].&[1] } ) ON COLUMNS FROM ( SELECT ( { [Rating].[Rating Category].&[38] } ) ON COLUMNS FROM ( SELECT ( {

[Benchmark].[Benchmark].&[1] } ) ON COLUMNS FROM ( SELECT ( { [Period].[Year-

Month].[Month].&[2006-03-01T00:00:00] } ) ON

COLUMNS FROM

[MIQB27])))) WHERE ( [Period].[Year-

Month].[Month].&[2006-03-01T00:00:00], [Rating].[Rating Category].&[38]

) CELL PROPERTIES

VALUE, BACK_COLOR,

FORE_COLOR, FORMATTED_VALUE,

FORMAT_STRING, FONT_NAME,

FONT_SIZE, FONT_FLAGS

It's hard to say without seeing your cube, but I suspect one reason for the difference is the fact that RS forces you to pivot your queries so that you only have the measures dimension on columns. This means that you have to put all the rest of your dimensions crossjoined on rows, which could potentially mean that the NON EMPTY operation has a lot of tuples to work on. How many members are there in the Sector Category, Benchmark, Portfolio and Scenario attributes?

Does changing the MDX in RS to be something like the following make a difference?

SELECT NON EMPTY { [Measures].[Duration], [Measures].[Weighting] } ON COLUMNS,
NON EMPTY { (
NONEMPTY(
[Sector].[Sector Category].[Sector Category].ALLMEMBERS
, { [Measures].[Duration], [Measures].[Weighting] })
* [Benchmark].[Benchmark].[Benchmark].ALLMEMBERS * [Portfolio].[Portfolio].[Portfolio].ALLMEMBERS *
[Scenario].[Scenario].[Scenario].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS FROM
( SELECT ( { [Scenario].[Scenario].&[1] } ) ON COLUMNS FROM ( SELECT ( { [Rating].[Rating Category].&[38] } ) ON COLUMNS FROM ( SELECT ( { [Benchmark].[Benchmark].&[1] } ) ON COLUMNS FROM ( SELECT ( { [Period].[Year- Month].[Month].&[2006-03-01T00:00:00] } ) ON COLUMNS FROM [MIQB27])))) WHERE ( [Period].[Year- Month].[Month].&[2006-03-01T00:00:00], [Rating].[Rating Category].&[38] ) CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS

Chris

|||I have changed the cube slightly - I had one dimension called Benchmark

which I removed it only has 3 leaf members and the ALL level. I had

the Benchmark code on another dimension as an attribute so I thought I

would use this instead. The RS query now worlks very quickly. On the

face of it the MDX query looks just as complex (see below). The only

thing I canm think of is as Benchmark was an attribute of Portfolio and

a dimension in its own right, it might have been doing some Cartesian

Product. But even so there were only 3 members.

Anyway, I am glad the issue has gone away - I was beginning to get worried about the use of RS on top of AS.

Regards

Paul

SELECT NON EMPTY

{ [Measures].[Weighting], [Measures].[Duration] } ON

COLUMNS, NON EMPTY { ([Rating].[Rating Category].[Rating

Category].ALLMEMBERS * [Sector].[Sector

Category].[Sector Category].ALLMEMBERS *

[Portfolio].[Benchmark Portfolio].[Portfolio].ALLMEMBERS

* [Scenario].[Scenario].[Scenario].ALLMEMBERS

) } DIMENSION PROPERTIES

MEMBER_CAPTION, MEMBER_UNIQUE_NAME

ON ROWS FROM ( SELECT ( STRTOSET(@.CurrencyofExposureCurrency, CONSTRAINED) ) ON COLUMNS FROM ( SELECT ( { [Scenario].[Scenario].&[1],

[Scenario].[Scenario].&[3] } ) ON COLUMNS FROM ( SELECT ( STRTOSET(@.PortfolioBenchmark,

CONSTRAINED) ) ON

COLUMNS FROM ( SELECT ( STRTOSET(@.PeriodYearMonth,

CONSTRAINED) ) ON

COLUMNS FROM

[MIQB28])))) WHERE ( IIF(

STRTOSET(@.PeriodYearMonth, CONSTRAINED).Count =

1, STRTOSET(@.PeriodYearMonth, CONSTRAINED), [Period].[Year- Month].currentmember ), IIF(

STRTOSET(@.PortfolioBenchmark, CONSTRAINED).Count =

1, STRTOSET(@.PortfolioBenchmark, CONSTRAINED), [Portfolio].[Benchmark].currentmember ), IIF(

STRTOSET(@.CurrencyofExposureCurrency, CONSTRAINED).Count =

1, STRTOSET(@.CurrencyofExposureCurrency, CONSTRAINED), [Currency of Exposure].[Currency].currentmember ) ) CELL

PROPERTIES VALUE,

BACK_COLOR, FORE_COLOR,

FORMATTED_VALUE, FORMAT_STRING,

FONT_NAME, FONT_SIZE,

FONT_FLAGS

|||

I am curious about your table structure. It looks like you are trying to do the same thing I am. Comparing portfolios to benchmarks for various groupings. Are weightings a calculated field? Do you have an overweight/underweight calculation? Do you use a PortfolioBenchmark dimension table or break them out?

Thanks for any help.

No comments:

Post a Comment