2. (More) Common Analysis Services
Multidimensional Design Mistakes and How to
Avoid Them
Chris Webb
3. Who Am I?
•
Chris Webb
• Email: chris@crossjoin.co.uk
• Twitter @Technitrain
•
•
Analysis Services consultant and trainer:
www.crossjoin.co.uk & www.technitrain.com
Co-author:
• MDX Solutions
• Expert Cube Development with SSAS 2008
• Analysis Services 2012: The BISM Tabular Model
•
•
SQL Server MVP
Blogger: http://cwebbbi.wordpress.com
4. Agenda
•
•
•
•
•
•
•
•
•
Why good cube design is a Good Thing
Using built-in best practices in BIDS
Precon recap
Parent/child pain
MDX vs modelling
Partition elimination
Unused and/or unprocessed aggregations
NON_EMPTY_BEHAVIOR
Cell Security
5. Why Good Design is Important!
• As if you needed reasons…?
• Good design
=
good performance
=
faster initial development
=
easy further development
=
simple maintenance
• This is not an exhaustive list, but a selection of design
problems and mistakes I’ve seen on consultancy
engagements
6. Best Practices in BIDS
• Don’t ignore the blue squiggly lines in BIDS!
– They sometimes make useful recommendations about
what you’re doing
• Actively dismissing them, with comments, is a useful
addition to documentation
• As always, official ‘best practices’ aren’t always best
practices in all situations
7. Common Design Mistakes
• Three questions need to be asked:
– What’s the problem?
– What bad things will happen as a result?
– What can I do to fix it (especially after I’ve gone into
production)?
• This is not a name-and-shame session!
8. Stuff From My Precon
•
•
•
•
Don’t use unfriendly names
Don’t create unnecessary attributes
Don’t do ETL in your DSV
Don’t create many small cubes instead of one big
one
• Don’t create one big cube instead of many smaller
ones
SQLDay 2013
9. Problem: Parent Child Hierarchies
• Parent Child hierarchies are the only way to model
hierarchies where you don’t know the number of
levels in advance
• They are also very flexible, leading some people to
use them more often than they should
10. Consequences: Parent Child
• Parent Child hierarchies can lead to slow query
performance
– No aggregations can be built at levels inside the
hierarchy
– Slow anyway
• They can also be a nightmare for
– Scoping advanced MDX calculations
– Dimension security
11. Fix: Parent Child
• If you know, or can assume, the maximum depth of your
hierarchy, there’s an alternative
• Normal user hierarchies can be made ‘Ragged’ with the
HideMemberIf property
– Hides members if their parent has no name, or the same
name as them
• Still has performance issues, but less than parent/child
• You can use the BIDS Helper “parent/child naturaliser” to
convert the underlying relational table to a level-based
structure
12. Problem: Over-reliance on MDX
• As with the DSV, it can be tempting to use MDX
calculations instead of making structural changes to
cubes and dimensions
• A simple example is to create a ‘grouping’ calculated
member instead of creating a new attribute
• Other examples include pivoting measures into a
dimension, or doing m2m in MDX
13. Consequences: Over-reliance on MDX
• MDX should always be your last resort:
• Pure MDX calculations are always going to be the
slowest option for query performance
• They are also the least-easily maintainable part of a
cube
• The more complex calculations you have, the more
difficult it is to make other calculations work
14. Fix: Over-reliance on MDX
• Redesigning your cube is a radical option but can pay
big dividends in terms of performance
• Risks breaking existing reports and queries but your
users may be ok with this to get more speed
15. Problem: Partition Elimination
• SSAS will usually only query the partitions that
contain the data it needs
• This depends on the way it stores the minimum and
maximum values of DataIDs (internal keys) in each
partition
SQLDay 2013
16. Consequences: Partition Elimination
• Slow performance – if SSAS queries too many
partitions for a single query
• Although the extra cache might make future queries
faster…
SQLDay 2013
17. Fix: Partition Elimination
•
•
•
•
Rewrite your MDX
Set the slice property
Order your members by DataID if possible
Use the connection string properties
Disable Prefetch Cache=True; Cache Ratio=1
SQLDay 2013
18. Problem: Unused Aggregations
• Aggregations are the most important SSAS feature
for performance
• Most people know they need to build some and run
the Aggregation Design Wizard…
• …but don’t know whether they’re being used or not
19. Consequences: Unused Aggregations
• Slow queries!
• If you haven’t built the right aggregations, then your
queries won’t get any performance benefit
• You’ll waste time processing these aggregations, and
waste disk space storing them
20. Fix: Unused Aggregations
• Design some aggregations!
• Rerun the Aggregation Design Wizard and set the
Aggregation Usage property appropriately
• Perform Usage-Based Optimisation
• Design aggregations manually for queries that are
still slow and could benefit from aggregations
21. Problem: Unprocessed Aggregations
• Even if you’ve designed aggregations that are useful
for your queries, you need to ensure they’re
processed
• Running a Process Update on a dimension will drop
some or all Flexible aggregations (depends on which
version of SSAS)
23. Fix: Unprocessed Aggregations
• Run a Process Default or a Process Index on your
cube after you have run a Process Update on any
dimensions
• Note that this will result in:
– Longer processing times overall
– More disk space used
• But it will at least mean that your queries run faster
24. Problem: Non_Empty_Behavior
• The Non_Empty_Behavior property was introduced
in SSAS 2000 as a performance hint
• It was very important in SSAS 2000/2005
• It says:
If Regular Measure A is Null
Then Calculated Measure B will be Null
• But it is usually set incorrectly
• And from SSAS 2008 on it is mostly unnecessary
SQLDay 2013
25. Consequences: Non_Empty_Behavior
• Setting Non_Empty_Behavior incorrectly can
– At best, make no difference to your performance
– At worst, result in incorrect query results
SQLDay 2013
26. Fix: Non_Empty_Behavior
• Don’t set it!
• Rewrite your calculations to check for null values:
IIF(
ISEMPTY(MEASURES.A),
NULL,
<CALCULATION>
)
SQLDay 2013
27. Problem: Cell Security
• Cell security allows you to secure individual cells in a
cube
• At first sight, it is the only option: it does things
dimension security cannot do…
SQLDay 2013
28. Consequences: Cell Security
• Setting cell security correctly can be very difficult
• Read and read contingent cell security can be even
more confusing
• Performance is often very bad with cell security:
– Forces cell-by-cell mode
– Forces Formula Engine caching to query scope
SQLDay 2013
29. Fix: Cell Security
• The answer is to use Dimension Security instead
• But how…?
• Create a new dimension that contains the
combinations of members that you want to secure
• Then use Dimension Security on it
• Doesn’t work if you need to secure measures
SQLDay 2013