{"id":216,"date":"2011-03-12T23:03:58","date_gmt":"2011-03-12T22:03:58","guid":{"rendered":"http:\/\/csopro.de\/biblog\/2011\/03\/performanceprobleme-bei-ssas-dimensionsabfargen-aus-ssrs\/"},"modified":"2014-12-31T18:27:57","modified_gmt":"2014-12-31T17:27:57","slug":"performanceprobleme-bei-ssas-dimensionsabfragen-aus-ssrs","status":"publish","type":"post","link":"https:\/\/www.csopro.de\/biblog\/2011\/03\/performanceprobleme-bei-ssas-dimensionsabfragen-aus-ssrs\/","title":{"rendered":"Performanceprobleme bei SSAS-Dimensionsabfragen aus SSRS"},"content":{"rendered":"<p>Nachdem wir in einem Projekt unseren Test-Datenbestand (12 Mio Fakten) auf den Produktiv-Bestand (73 Mio Fakten) erweitert hatten, zeigten die Berichte (SSRS 2008 R2) massiv schlechte Antwortszeiten in bestimmten Berichten auf unseren Cube (SSAS 2008 R2) &#8211; jeweils nach der Cubeaufbereitung. Somit war klar, dass Ursache war, dass einige der im Bericht verwendeten Abfragen nicht im Cache waren, da dieser ja durch die inkrementelle Dimensionsaufbereitung und Aufbereitung einiger Cubepartitionen gel\u00f6scht wird.<\/p>\n<p>Naheliegende Strategien waren:<\/p>\n<ul>\n<li>Aufteilung in mehr Partitionen unter Angabe der Slice-Property<\/li>\n<li>Verbesserte Aggregationen \u00fcber Usage based Aggregation Design<\/li>\n<li>Cache Warming &#8211; Strategien<\/li>\n<\/ul>\n<p>All das brachte uns aber nicht wirklich weiter.<\/p>\n<p>Letztendlich stellte sich aber heraus, dass die Ursache gar nicht in den (tlw. komplexen) Abfragen zur Ermittlung der Fakten zu suchen war, sondern in &#8222;Dimensions-Abfragen&#8220;. Damit meine ich folgendes: Unsere Berichte werden (aus einer eigenen Web-Applikation heraus) mit Parametern aufgerufen, die IDs sind (eigentlich die Member Unique Names, also z.B. Datum.Jahr.&amp;[2010]). Dabei haben die Parameter (aus Performancegr\u00fcnden) keine Datasets, die alle verf\u00fcgbaren Werte enthalten. Nun wollen wir aber in dem Bericht nat\u00fcrlich auch den \u00fcbergebenen Wert im Klartext anzeigen, also in obigem Beispiel das Jahr 2010. Deswegen mussten also einfache Abfragen her, die aus dem Member Unique Name den Klartext (Member Caption) ermitteln.<\/p>\n<p>In unserem Projekt hatten wir uns darauf geeinigt, wenn m\u00f6glich den SSRS-Designer f\u00fcr SSAS-Abfragen zu verwenden, um eine gute Wartbarkeit (ohne tiefere MDX-Kenntnisse) zu erreichen.<\/p>\n<p>Damit gibt es zwei einfache Arten, dieses Problem zu l\u00f6sen:<\/p>\n<p>Die erste Art, hat eine Spalte &#8211; das Jahr &#8211; und zus\u00e4tzlich den (MultiSelect) Report Parameter als Parameter f\u00fcr die Abfrage:<\/p>\n<p><a title=\"Langsame Abfrage im SSRS-Designer f\u00fcr SSAS-Abfragen\" href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/langsamwizard.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/langsamwizard-small.jpg\" alt=\"Wizard f\u00fcr die langsame Abfrage\" width=\"450\" height=\"182\" \/><\/a><br \/>\n(Bild zum Verg\u00f6\u00dfern anklicken!)<\/p>\n<p>Als MDX ergibt sich:<\/p>\n<blockquote><p>SELECT { } ON COLUMNS, { ([Datum].[Jahr].[Jahr].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS FROM ( SELECT ( STRTOSET(@DatumJahr, CONSTRAINED) ) ON COLUMNS FROM [Verkaeufe]) CELL PROPERTIES VALUE<\/p><\/blockquote>\n<p>Man kann auch die Abfrage etwas erweitern:<\/p>\n<p>Man f\u00fcgt ein berechnets Measure (in diesem Fall namens &#8222;UniqueName&#8220;) mit dem MDX<\/p>\n<blockquote><p>[Datum].[Jahr].CurrentMember.UniqueName<\/p><\/blockquote>\n<p>hinzu:<\/p>\n<p><a title=\"Schnelle Abfrage im SSRS-Designer f\u00fcr SSAS-Abfragen\" href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/schnellwizard.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/schnellwizard-small.jpg\" alt=\"Wizard der schnellen Abfrage\" width=\"450\" height=\"236\" \/><\/a><br \/>\n(Bild zum Verg\u00f6\u00dfern anklicken!)<\/p>\n<p>Damit ergibt sich folgendes MDX:<\/p>\n<blockquote><p>WITH MEMBER [Measures].[UniqueName] AS [Datum].[Jahr].CurrentMember.UniqueName SELECT NON EMPTY { [Measures].[UniqueName] } ON COLUMNS, NON EMPTY { ([Datum].[Jahr].[Jahr].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS FROM ( SELECT ( STRTOSET(@DatumJahr, CONSTRAINED) ) ON COLUMNS FROM [Verkaeufe]) CELL PROPERTIES VALUE, BACK_COLOR, FORE_COLOR, FORMATTED_VALUE, FORMAT_STRING, FONT_NAME, FONT_SIZE, FONT_FLAGS<\/p><\/blockquote>\n<p>Anmerkung: Das dabei enstehende versteckte Dataset zum Bef\u00fcllen der &#8222;verf\u00fcgbaren Werte&#8220; des Parameters l\u00f6schen wir, da wir ja keine &#8222;verf\u00fcgbaren Werte&#8220; anzeigen wollen (unsere Dimension hatte zu viele Eintr\u00e4ge).<\/p>\n<p>Beide Abfragen scheinen dasselbe zu tun und mit der selben Performance. Dies ist aber ein Trugschluss!<\/p>\n<p>Leeren wir zun\u00e4chst (und vor Ausf\u00fchrung eines neuen Test-Statements) den SSAS-Cache mit<\/p>\n<blockquote><p>&lt;ClearCache xmlns=&#8220;http:\/\/schemas.microsoft.com\/analysisservices\/2003\/engine&#8220;&gt;<br \/>\n&lt;Object&gt;<br \/>\n&lt;DatabaseID&gt;SimpleCube&lt;\/DatabaseID&gt;<br \/>\n&lt;CubeID&gt;Verkaeufe&lt;\/CubeID&gt;<br \/>\n&lt;\/Object&gt;<br \/>\n&lt;\/ClearCache&gt;<\/p><\/blockquote>\n<p>(siehe dazu auch: <a href=\"http:\/\/www.ssas-info.com\/analysis-services-faq\/27-mdx\/133-mdx-how-do-i-clear-analysis-services-ssas-database-cache\" target=\"_blank\">http:\/\/www.ssas-info.com\/analysis-services-faq\/27-mdx\/133-mdx-how-do-i-clear-analysis-services-ssas-database-cache<\/a>)<\/p>\n<p>Dann betrachten wir die Darstellung im SQL Server Profiler (mit den Standard-Einstellungen f\u00fcr den SSAS):<\/p>\n<p>Die erste Abfrage ergibt folgendes Bild:<\/p>\n<p><a title=\"Ergebnis im SQL Server Profiler f\u00fcr die langsame Abfrage\" href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/sqlprofilerlangsam.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/sqlprofilerlangsam-small.jpg\" alt=\"SQL Profiler Ergebnis der langsamen Abfrage\" width=\"450\" height=\"182\" \/><\/a><br \/>\n(Bild zum Verg\u00f6\u00dfern anklicken!)<\/p>\n<p>Schauen wir uns die einzelnen Zeilen an:<\/p>\n<ul>\n<li>Session Initialize &#8211; spricht f\u00fcr sich<\/li>\n<li>Query Begin: Hier f\u00e4ngt die Abfrage an &#8211; im unteren Bereich sieht man das MDX und die Parameterwerte f\u00fcr die @Parameter im MDX<\/li>\n<li>Progress Report Begin: Daten aus einer Partition werden gelesen (!), d.h. von der Festplatte in den Speicher \u00fcbernommen.<\/li>\n<li>Progress Report End: das dazugeh\u00f6rige Ende<\/li>\n<li>Query SubCube: die gelesenen Daten werden verwendet, um die Abfrage zu beantworten (in diesem Fall Non-Cache)<\/li>\n<li>Query End: Das Ende der Abfrage<\/li>\n<\/ul>\n<p>Die zweite Abfrage ergibt ein anderes Bild:<\/p>\n<p><a title=\"Ergebnis im SQL Server Profiler f\u00fcr die schnelle Abfrage\" href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/sqlprofilerschnell.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/sqlprofilerschnell-small.jpg\" alt=\"SQL Profiler Ergebnis der schnellen Abfrage\" width=\"450\" height=\"59\" \/><\/a><br \/>\n(Bild zum Verg\u00f6\u00dfern anklicken!)<\/p>\n<p>Hier sehen wir, dass kein Zugriff auf eine Partition erfolgt!<\/p>\n<p>Der Zugriff auf die Partition ist nat\u00fcrlich sch\u00e4dlich, da er bei gro\u00dfen Datenmengen lang dauern kann, zumal er gar nicht ben\u00f6tigt wird, da wir ja nur Dimensions-Element-Bezeichnungen abfragen wollen.<br \/>\nEs ist nicht erkl\u00e4rbar, warum SSAS hier dennoch auf die Fakten zugreift.<br \/>\nDeswegen ist die zweite Abfrage auf jeden Fall vorzuziehen!<\/p>\n<p>Noch ein interessante Anmerkung zum Schluss: Wenn man die erste Abfrage im SQL Server Management Studio ausf\u00fchrt, ist sie auch nicht langsam. Da im Management Studio keine parametrisierten Abfragen m\u00f6glich sind, muss man dazu die Parameter durch die entsprechenden Strings ersetzen, und erh\u00e4lt somit folgendes MDX:<\/p>\n<blockquote><p>SELECT { } ON COLUMNS, { ([Datum].[Jahr].[Jahr].ALLMEMBERS ) } DIMENSION PROPERTIES MEMBER_CAPTION, MEMBER_UNIQUE_NAME ON ROWS FROM ( SELECT ( STRTOSET(&#8222;{ [Datum].[Jahr].&amp;[2001],[Datum].[Jahr].&amp;[2008] }&#8220;, CONSTRAINED) ) ON COLUMNS FROM [Verkaeufe]) CELL PROPERTIES VALUE<\/p><\/blockquote>\n<p>F\u00fchrt man dieses MDX aus (nachdem man den Cache geleert hat), so erh\u00e4lt man folgendes Bild:<\/p>\n<p><a title=\"Ergebnis im SQL Server Profiler f\u00fcr die langsame Abfrage, ausgef\u00fchrt im Management Studio\" href=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/profilerlangsamssms.jpg\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.csopro.de\/biblog\/wp-content\/uploads\/2011\/03\/profilerlangsamssms-small.jpg\" alt=\"Ergebnis des Profilers der langsamen Abfrage ausgef\u00fchrt im Management Studio\" width=\"450\" height=\"170\" \/><\/a><br \/>\n(Bild zum Verg\u00f6\u00dfern anklicken!)<\/p>\n<p>Man sieht hier also auch nur ein Query Begin und ein Query End, also auch keinen Zugriff auf die Cube-(bzw. Partitions-)Daten.<\/p>\n<p>Dies hatte uns die Fehlersuche erschwert, da wir nat\u00fcrlich zun\u00e4chst auf der Suche nach dem verantwortlichen Statement alle Statements im SQL Server Profiler mitgeschnitten und dann einzeln im Management Studio ausgef\u00fchrt hatten, was &#8211; wie eben gesehen &#8211; das problematische Statement leider nicht offenbart.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nachdem wir in einem Projekt unseren Test-Datenbestand (12 Mio Fakten) auf den Produktiv-Bestand (73 Mio Fakten) erweitert hatten, zeigten die Berichte (SSRS 2008 R2) massiv schlechte Antwortszeiten in bestimmten Berichten auf unseren Cube (SSAS 2008 R2) &#8211; jeweils nach der Cubeaufbereitung. Somit war klar, dass Ursache war, dass einige der im Bericht verwendeten Abfragen nicht &hellip; <a href=\"https:\/\/www.csopro.de\/biblog\/2011\/03\/performanceprobleme-bei-ssas-dimensionsabfragen-aus-ssrs\/\" class=\"more-link\"><span class=\"screen-reader-text\">Performanceprobleme bei SSAS-Dimensionsabfragen aus SSRS<\/span> weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,11,5],"tags":[25,23],"class_list":["post-216","post","type-post","status-publish","format-standard","hentry","category-integrationservices","category-reportingservices","category-projekte","tag-performance","tag-tabular"],"_links":{"self":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/216","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/comments?post=216"}],"version-history":[{"count":1,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/216\/revisions"}],"predecessor-version":[{"id":269,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/posts\/216\/revisions\/269"}],"wp:attachment":[{"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/media?parent=216"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/categories?post=216"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csopro.de\/biblog\/wp-json\/wp\/v2\/tags?post=216"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}