Jürgen Auer
Legendäres Mitglied
Innerhalb von Server-Daten gibt es die Möglichkeit, Kalenderdaten 'quer' anzuzeigen, wie das in der Kopfzeile von diesem Online-Kalender gezeigt ist: Ein Block von acht Wochen, darunter in Form einer Balkendarstellung bsp. diverse mehrtägige Veranstaltungen, die nach Kriterien der ersten Spalte gegliedert sind.
Man denke bsp. an einen Pool von Ressourcen (Personen, Tools wie Beamer o.ä.), die alle in der ersten Spalte links stehen. Die Balken zeigen dann Einsatzzeiten o.ä. an. Man sieht also auf einen Blick, daß eine Ressource für einen bestimmten Zeitraum bereits blockiert / im Einsatz ist.
Grundsätzliches Problem: Man will blättern, also ändern sich die Spaltenüberschriften. Ferner ist die Zahl der Zeilen variabel - neue Ressourcen kommen hinzu.
Grundsätzliches Prinzip: Eine Abfrage, die zu jedem Datum innerhalb dieser acht Wochen eine lange Zeile ausgibt, pro Ressource eine oder mehrere Spalten. Diese Abfrage wird bei der Ausgabe 'gekippt', so daß die Datumsangaben oben, die Ressourcen links und dann eben - in Abhängigkeit von den Ergebnissen - Zellen per Colspan zusammengefaßt werden, eingefärbt sind und bsp. einen Link auf Detailinformationen enthalten.
CODE Select A._tbl_CalendarId, A.thisDay,
X1.Spalte1 As X1_1, X1.Spalte2 As X1_2,
X2.Spalte1 As X2_1, X2.Spalte2 As X2_2,
usw. für jede Ressource
From _tbl_Calendar As A
Left Join (Select alle Informationen zur Ressource 1) As X1
On A.thisDay Between X1.Beginn And X1.Ende
Left Join (Select alle Informationen zur Ressource 2) As X2
On A.thisDay Between X2.Beginn And X2.Ende
... analoge LeftJoins für jede Ressource
Where A.thisDay Between @start_date And @end_date
Also eine interne Tabelle (ist für alle SD-Kunden dieselbe), die eine Spalte mit allen Tagen innerhalb des Intervalls liefert, dann zu jeder Ressource einen LeftJoin (mit den Ressourcen-Ids als eindeutigen Nummern für den Alias), oben werden die Spalten ausgegeben.
Das lief seit Monaten problemlos mit einem Typ von Ressourcen.
Eigentlich einfacher Wunsch: Einen zweiten Ressourcentyp unten ergänzen. Also fröhlich gebaut, im Prinzip mußte 'fast nur' diese automatisch generierte Abfrage angepaßt werden.
Und was passiert: Der ursprüngliche Code benötigte beim Erstaufruf vielleicht 5 - 10 Sekunden zur Kompilierung (Erstellung eines Ausführungsplans, der dann gecacht wird und wiederholt verwendet werden kann). Zwar lang, das ließ sich aber über einen nächtlichen Aufruf abfangen. Nun dagegen (etwa 25 weitere Ressourcen, also 25 Left Joins, noch ohne Spalten) - dauert das reine Kompilieren mehr als 5 Minuten (ein Serverkern ist da über 5 Minuten zu 100 % ausgelastet).
Bei den Unterabfragen gab es Inner Joins -> Left Joins draus gemacht, keine Änderung. Indices ergänzt, keine Änderung, eher Verschlechterung.
Worin besteht das Problem und wie läßt es sich lösen? Die Lösung poste ich hier.
PS: Es ist eine Winzigkeit, welche die Kompilierungszeit in den Bereich weit unter einer Sekunde befördert.
Man denke bsp. an einen Pool von Ressourcen (Personen, Tools wie Beamer o.ä.), die alle in der ersten Spalte links stehen. Die Balken zeigen dann Einsatzzeiten o.ä. an. Man sieht also auf einen Blick, daß eine Ressource für einen bestimmten Zeitraum bereits blockiert / im Einsatz ist.
Grundsätzliches Problem: Man will blättern, also ändern sich die Spaltenüberschriften. Ferner ist die Zahl der Zeilen variabel - neue Ressourcen kommen hinzu.
Grundsätzliches Prinzip: Eine Abfrage, die zu jedem Datum innerhalb dieser acht Wochen eine lange Zeile ausgibt, pro Ressource eine oder mehrere Spalten. Diese Abfrage wird bei der Ausgabe 'gekippt', so daß die Datumsangaben oben, die Ressourcen links und dann eben - in Abhängigkeit von den Ergebnissen - Zellen per Colspan zusammengefaßt werden, eingefärbt sind und bsp. einen Link auf Detailinformationen enthalten.
CODE Select A._tbl_CalendarId, A.thisDay,
X1.Spalte1 As X1_1, X1.Spalte2 As X1_2,
X2.Spalte1 As X2_1, X2.Spalte2 As X2_2,
usw. für jede Ressource
From _tbl_Calendar As A
Left Join (Select alle Informationen zur Ressource 1) As X1
On A.thisDay Between X1.Beginn And X1.Ende
Left Join (Select alle Informationen zur Ressource 2) As X2
On A.thisDay Between X2.Beginn And X2.Ende
... analoge LeftJoins für jede Ressource
Where A.thisDay Between @start_date And @end_date
Also eine interne Tabelle (ist für alle SD-Kunden dieselbe), die eine Spalte mit allen Tagen innerhalb des Intervalls liefert, dann zu jeder Ressource einen LeftJoin (mit den Ressourcen-Ids als eindeutigen Nummern für den Alias), oben werden die Spalten ausgegeben.
Das lief seit Monaten problemlos mit einem Typ von Ressourcen.
Eigentlich einfacher Wunsch: Einen zweiten Ressourcentyp unten ergänzen. Also fröhlich gebaut, im Prinzip mußte 'fast nur' diese automatisch generierte Abfrage angepaßt werden.
Und was passiert: Der ursprüngliche Code benötigte beim Erstaufruf vielleicht 5 - 10 Sekunden zur Kompilierung (Erstellung eines Ausführungsplans, der dann gecacht wird und wiederholt verwendet werden kann). Zwar lang, das ließ sich aber über einen nächtlichen Aufruf abfangen. Nun dagegen (etwa 25 weitere Ressourcen, also 25 Left Joins, noch ohne Spalten) - dauert das reine Kompilieren mehr als 5 Minuten (ein Serverkern ist da über 5 Minuten zu 100 % ausgelastet).
Bei den Unterabfragen gab es Inner Joins -> Left Joins draus gemacht, keine Änderung. Indices ergänzt, keine Änderung, eher Verschlechterung.
Worin besteht das Problem und wie läßt es sich lösen? Die Lösung poste ich hier.
PS: Es ist eine Winzigkeit, welche die Kompilierungszeit in den Bereich weit unter einer Sekunde befördert.