Building State of the art presentation tiers Nauzad Kapadia [email protected].
Nauzad Kapadia Principal Consultant Quartz Systems [email protected] T: @nauzadk.
-
Upload
berniece-williams -
Category
Documents
-
view
238 -
download
0
Transcript of Nauzad Kapadia Principal Consultant Quartz Systems [email protected] T: @nauzadk.
Optimizing Time-Series Calculations in SSAS
Nauzad KapadiaPrincipal ConsultantQuartz [email protected]: @nauzadk
Session Objectives and Takeaways
Review existing approaches to time-series analysis in SSAS
Calculated measuresTime intelligence wizardCustom built time utility dimensions
Understand issues with existing approaches Calculate measure explosionNo ability to account for comprehensive time dimensions Weak/non-existent error handling capabilities
Introduce a “new” approach that addresses existing issues and provides end-users with flexibility, simplicity, and good performance
Time-Series AnalysisThe 2 types of calculations we will focus on todayPeriod-To-Period
Also called Prior-Period calculationsUse the MDX function .PrevMember
WITH MEMBER [Measures].[GDP_Change] AS [Measures].[GDP Billions Current USD] - ( [Measures].[GDP Billions Current USD], [DimDate].[H-
Decade].CurrentMember.PrevMember )
SELECT {[Measures].[GDP Billions Current USD], [Measures].[GDP_Change] } ON COLUMNS ,
NON EMPTY Hierarchize( {[DimDate].[H-Decade].[Decade Desc].Members, [DimDate].[H-Decade].[Calendar Year].Members
} ) ON ROWS FROM [GovtDebtAnalysis]WHERE ([DimCountry].[Country].[United States]) ;
Time-Series AnalysisThe 2 types of calculations we will focus on todaySame-Period-Last-Year
Also called Parallel-Period or Year AgoUse the MDX function .ParallelPeriod
Can alternatively use the .Lag function on dimension attributes
WITH MEMBER [Measures].[UnemploymentAvg_PP_Change] AS([Measures].[UnemploymentAvg] ) -( [Measures].[UnemploymentAvg], ParallelPeriod( [DimDate].[H-
Year].[Calendar Year], 1, [DimDate].[H-Year].CurrentMember ) )
SELECT { [Measures].[UnemploymentAvg], [Measures].[UnemploymentAvg_PP_Change] } ON COLUMNS ,
NON EMPTY Hierarchize( {[DimDate].[H-Year].[Calendar Year].Members, [DimDate].[H-Year].[Calendar Qtr].Members, [DimDate].[H-Year].[Month].Members } ) ON ROWS FROM [GovtDebtAnalysis]WHERE ([DimCountry].[Country].[United States]);
Time-Series AnalysisWhy not just create calculated members?
Calculated measure explosionConsider the GovtDebtAnalysis sample cube-
7 (visible) measures3 time hierarchies, and 2 standalone dimension attributes
To provide a Prior-Period and Parallel-Period calculation for each measure (across all time hierarchies and dimension attributes) would require an additional 70 calculated measures
Error handling / misleading resultsNon-trivial to implement, no fun to duplicate
The BI Wizard – Time Intelligence
Available since SSAS 2005, built-in implementation of a time utility dimensionAdds a named calculation (e.g. H-Year DimDate Calculations) to the Date dimension table (in the DSV) with a static value
Similarly named attribute is added to the Date dimension
Calculated members are added to the attribute
(Some) error handling logic is included in calculationsAssignments used in member definitions
What is a Shell Dimension
A Dimension with ONE attribute with ONE member.Every record in the fact table is mapped to the ONE member.This ONE member becomes the ANCHOR member.Allows modification of MDX-instead of specifying a measure, we can specify the anchor.
GDP PrYr Chg = ([Time].[Calendar Hierarchy].CurrentMember.Lag(1), [Measures].[GDP]), (ParallelPeriod([Time].[Calendar Hierarchy].[Year], 1), [Measures].[Sales Amount]))
GDP PrYr Chg = ([Time].[Calendar Hierarchy].CurrentMember.Lag(1), [Anchor Member]), (ParallelPeriod([Time].[Calendar Hierarchy].[Year], 1), [Anchor Member]))
The BI Wizard – Time IntelligenceIssues/Limitations
Calculations are limited to a single time dimension hierarchy
May not work for other hierarchies (and standalone dimension attributes)
Role-playing dimensions (based on time)Error handling (missing data at tail and head of time)Somewhat verbose and fixed
Year Over Year Growth = Parallel-PeriodQuarter Over Quarter and Month Over Month are both PriorPeriod – what about days, decades, centuries, etc.?
New approachAn enhanced time utility dimension
Based on concepts from:David’s Shroyer’s white paper "A Different Approach to Implementing Time Calculations in SSAS“Mosha Pasumansky’s blog entry "Time Calculations in UDM: Parallel Period“ (Note – Mosha points out a few limitations and performance problems with David’s approach – some of which David has since addressed)
Use David’s framework for creating a time utility dimensionIntegrate performance optimizations from Mosha’s whitepaperUse an explicit (attribute) based method of scoping the calculations across the entire time dimension
And account for role playing dimensions (based on the time dimension) via script duplication
New approachSetting it up1. Add a new dimension attribute to the existing
time/date dimension.• Add a named calculation (e.g. TimeCalcs) in the Date
dimension table (in the DSV); assign a static value (Current)
2. Create a new dimension.• Create a shared dimension (DimTimeCalcs); the
dimension contains no hierarchies (just a single attribute – TimeCalcs)
• Set the TimeCalcs attribute IsAggregatable property = false, and change the DefaultMember to [Current]
3. Add the new dimension to the cube.• Set the relationship type (for each measure group) to
referenced• Set the HierarchyUniqueNameStyle property to
ExcludeDimensionName (to simplify later MDX references)
New approachSetting it up Continued4. Add the time calculations to the cube.
• Define PriorPeriod and YearAgo members with a default Null value
• Scope calculation to each desired dimension attribute e.g.
CREATE MEMBER CURRENTCUBE.[TimeCalcs].[PriorPeriod] AS Null;CREATE MEMBER CURRENTCUBE.[TimeCalcs].[YearAgo] AS Null;
/* Define a Prior Period value for the Century attribute. Note that we do not define a YearAgo value. */Scope( [DimDate].[Century].[Century].Members ); -- Prior Period calculation ( [TimeCalcs].[PriorPeriod] = ( [DimDate].[Century].CurrentMember.PrevMember ,[TimeCalcs].[Current] ) ); End Scope;
New approachSetting it up ContinuedScope( [DimDate].[Calendar Qtr].[Calendar Qtr].Members); -- Prior Period ( ( [TimeCalcs].[PriorPeriod] , { [Measures].[CPI_Base2005], [Measures].[UnemploymentAvg] } ) = ( [DimDate].[Calendar Qtr].CurrentMember.PrevMember ,[TimeCalcs].[Current] ) ); -- Year Ago ( ( [TimeCalcs].[YearAgo] , { [Measures].[CPI_Base2005], [Measures].[UnemploymentAvg] } ) = ( [DimDate].[Calendar Qtr].CurrentMember.Lag(4) ,[TimeCalcs].[Current] ) ); End Scope;
New ApproachHandling role-playing dimensions
Tried a few different ways of working with role-playing dimensions, but the approach that worked….Copy and Paste
Specifically, copy and paste all Scope statements, replacing the dimension name with role playing dimension name
/* Define a Prior Period value for the Century attribute. Note that we do not define a YearAgo value. */Scope( [ShipDate].[Century].[Century].Members ); -- Prior Period calculation ( [TimeCalcs].[PriorPeriod] = ( [ShipDate].[Century].CurrentMember.PrevMember ,[TimeCalcs].[Current] ) ); End Scope;
New approachScoping on [all of] the dimension attributes
Scoping on all dimension attributes may seem like overkillE.g. When attribute relationships (and hierarchies?) are properly configured in the Date dimension, I can scope on the Date attribute - and rely on coordinate overwrite rules to propagate calculations up to month, quarter, semester, and year
However, building, understanding, and relying on attribute relationships (and understanding coordinate overwrite rules) is difficult
Try taking the default AdventureWorks 2008 DW implementation. Notice how the attribute relationships are configured for Fiscal Quarter and Semester – calculations don’t work without explicit attribute definitions on these (and other) attributes
Trying to implement an approach that will work well with new and existing cubes
E.g. AdventureWorks 2008 DW’s Date Dimension starting July 1
Other ConsiderationsDe-selection of Calculated Members
Analysis Services 2005 SP2 (and 2008) breaks Excel 2007/2010 calculated member selection
Calculated members cannot be deselectedMulti-member utility dimensions can be unwieldy
Other ConsiderationsDe-selection Workarounds
Marco Russo’s DateTool Dimension ProjectConvert calculated members into “real” members (via a Union Join in the DSV view defining the dimension)
Then override in the calculation script of the cubeInteresting implementation of the time utility dimension – no relationship to any of the measure groups Worked well for my sample cube, but not with AdventureWorks 2008 sample
Named SetsExcel 2010 lets a user define them; otherwise you can define them in the cubeNot a great solution - but it can help
What Else?
Related Content
March 2010 Edition of SQL Server Magazinewww.sqlmag.com/article/sql-server-analysis-services/optimizing-time-based-calculations-in-ssas-.aspxAdditional Web only article provides an introduction to time-series analysis
David Shroyer’s whitepaperhttp://www.obs3.com/pdf/A%20Different%20Approach%20to%20Time%20Calculations%20in%20SSAS.pdf
Mosha Pasumansky’s optimizations for David’s ParallelPeriod calculations
http://sqlblog.com/blogs/mosha/archive/2006/10/25/time-calculations-in-udm-parallel-period.aspx
PTPower Utility for Creating Calculated Members in Excel 2007/2010
www.sqlserverpower.com/UtilityDetail/PTPower.aspx