Analysis Services Best Practices: Performante Many-To-Many Beziehungen

21. März 2011

Das Problem

Oftmals birgt ein Geschäftsszenario das Problem, dass ein Fakt nicht nur zu einem Dimensionseintrag zugeordnet werden muss, sondern zu beliebig vielen. Ein reales Beispiel aus der Praxis ist z.B. eine Transaktion, die in verschiedenen Reports vorkommen kann, wobei die Menge an ca. 200 Reports eine eigene Dimension darstellt. Da der Anwender im beschrieben Analyseszenario stets einen Report auswählen muss und keine Mehrfachauswahl treffen darf, wäre eine fachlich mögliche Lösung sogar das Vervielfachen der Fakten für jeden Report. Es ist aber leicht einzusehen, dass dies schon alleine wegen des verschwendeten Speicherplatzes keine sinnvolle Lösung ist. In diesem Fall bringt eine N:M Beziehung, wie sie standardmäßig von SSAS ab der Version 2005 unterstützt wird, die Lösung.

Many-To-Many in SSAS

Vorweg: Wer sich wirklich tiefgehend mit dem Thema N:M Beziehungen in SSAS auseinandersetzen möchte, der sei auf das Dokument The many-to-many revolution verwiesen. Hier werden verschiedene Szenarien beschrieben, in denen eine solche Beziehung angewendet werden kann, und die Umsetzung wird detailliert dargestellt. In diesem Artikel geht es darum, anhand eines Beispielszenarios die Umsetzung einer Many-To-Many Beziehung zu zeigen und auf einige Besonderheiten im Hinblick auf die Performance hinzuweisen.

Wie bereits gesagt werden N:M-Beziehungen von SSAS unterstützt. Dabei sind stets vier Tabellen beteiligt: 1) die Faktentabelle, 2) eine Dimensionstabelle, 3) eine Zwischen- oder Zuordnungstabelle, und schließlich 4) die Dimensionstabelle, die eine N:M-Beziehung zur Faktentabelle hat. Die folgende Abbildung zeigt diese vier Tabellen für das oben beschriebene Szenario.

image

Die Tabelle DimReportCriteria ist im Cube-Frontend später nicht sichtbar. Sie dient lediglich als Hilfstabelle, um die N:M-Beziehung abbilden zu können. Das Feld DimReportCriteriaID ist ein künstlich erzeugter Schlüssel, der für eine Kombination von Attributen einer Transaktion steht. Diese Kombination aus Attributen beinhaltet die Information nach der entschieden wird, ob eine Transaktion in einen Report einfließen soll oder nicht. Das Erzeugen eines künstlichen Integer-Werts für das Abbilden von N:M-Beziehungen ist entscheidend für die spätere Performance bei MDX Abfragen gegen den Cube. Man könnte stattdessen die Beziehung auch über die tatsächlichen Attribute herstellen, was aber deutlich langsamer und speicherplatzintensiv wäre, da diese häufig textueller Natur sind. Die Kombination der Attributausprägungen (AttributeA und AttributeB), die durch eine DimReportCriteriaID repräsentiert wird, sind zwar in der Dimensionstabelle gespeichert, müssen/sollen aber nicht in den Cube übernommen werden. Die folgenden beiden Abbildungen zeigen die Data Source View sowie den Dimension Usage Tab für den Beispielcube.

image_thumb[1]

image

Die Beziehung der “Dim Report Criteria” zur “Fakt Transaktion” ist eine normale 1:N Beziehung über das Feld DimReportCriteriaID, genau wie zur “Zuo Report”. Die Dimension “Dim Report” besitzt ebenfalls eine Beziehung vom Typ “Regular” zur “Zuo Report”. All diese Beziehungen sind Voraussetzung, dass eine Many-To-Many Beziehung zwischen der “Dim Report” und der “Fakt Transaktion” hergestellt werden kann. Dazu wählt man im “Define Relationship” Fenster als Typ “Many-to-Many” und selektiert als Intermediate Measure Group die “Zuo Report”.

image

Die Größe der Zwischentabelle

Die Größe der Zwischentabelle ist ein weiteres wichtiges Kriterium für die Performance von N:M-Beziehungen. Im SSAS Performance Guide werden verschiedene Szenarien durchgespielt und auf die Performance getestet. Aus eigener Erfahrung kann ich sagen, dass bei richtiger Modellierung und dem Bilden von Aggregationen die Größe der Zwischentabelle beachtlich sein kann, bevor es zu ernsthaften Performanceproblemen kommt. In dem Beispielprojekt umfasste die Zuordnungstabelle zwar nur 3 Mio. Zeilen, dafür wurde komplett auf eine Partitionierung verzichtet, was noch eine weitere Option für die Performanceverbesserung darstellt. Durch die Verwendung von Partitionen kann die Größe der Tabelle noch deutlich größer sein.

Das Verwenden einer Parent-Child Hierarchie in der Dimension in Kombination mit einem Unary Operator kann die Performance jedoch verschlechtern. Man sollte sich generell die Verwendung des Unary Operators gut überlegen und wirklich nur dann einsetzen, wenn es notwendig ist. Dies gilt insbesondere auch für Many-To-Many Beziehungen. Die Probleme sind in der Version 2005 noch ausgeprägter und wurden in der Version 2008 deutlich verbessert. Leider gibt es zumindest in der Version 2005 einen bekannten Bug im Zusammenhang mit dem Unary Operator und Many-To-Many Beziehungen, der diese Option komplett unbrauchbar macht.

Vorsicht bei Unary Operators in SSAS 2005

Der Fehler äußert sich dadurch, dass der Unary Operator auf unterster Ebene zwar korrekt angewendet wird, auf der nächst höheren und darüber jedoch ignoriert wird. So stimmen die Summen auf der vorletzten Ebene, alle darüber sind aber falsch. Das Problem tritt allerdings nur bei dem “+” Operator auf.

Gewichtung der Beziehung

Vielleicht ist dem einen oder anderen aufgefallen, dass in der Tabelle ZuoReport ein Feld Faktor existiert. Dieser Faktor wurde im Beispielprojekt in einer Measure Expression verwendet, um bestimmen zu können mit welchem Faktor die Transaktion in den Report einfließt. Measure Expressions bieten hierfür eine sehr gute und performante Möglichkeit und sollten einem Calculated Measure wenn möglich vorgezogen werden. Eine Measure Expression kann allerdings immer nur einen Faktor beinhalten. Ausdrücke wie [Measures].[Count] * [Measures].[Faktor] funktionieren also, während [Measures].[Count] * [Measures].[Faktor] * [Measures].[Faktor2] zu einem Fehler führt. Zudem versteht eine Measure Expression nur die Operatoren "*" und "/".

Fazit

Das Fazit lautet also: Many-To-Many Beziehungen bieten eine hervorragende Option, um komplexe Szenarien im Cube abzubilden. Zahlreiche Beispiele dafür finden sich in The many-to-many revolution. SSAS unterstützt N:M-Beziehungen seit der Version 2005. Beachtet man zudem die folgenden Punkte…

  • Künstliche Integer-Schlüssel für die Zuordnungen verwenden
  • Aggregationen auf der Zwischentabelle bilden
  • Zwischentabelle partitionieren, wenn möglich und wenn sehr groß

… so wird die Performance bei MDX Abfragen auch bei der Verwendung von N:M-Beziehungen sehr gut sein.