Wir haben eine Tabelle mit räumlichen Daten und einigen Attributen und müssen diese aggregieren, damit sie in verschiedenen Abfragen verwendet werden können. Wir haben den Mechanismus, um die Aggregation im laufenden Betrieb über gespeicherte CLR-Prozeduren durchzuführen, aber ich habe mich gefragt, wie diese aggregierten Daten in SQL Server 2008 R2 am besten zwischengespeichert werden können, da die Aggregation sehr langsam ist.
Wir haben also einen Tisch wie diesen:
[TableId] [int] NOT NULL,
[FeatureId] [int] NOT NULL,
[MeasureFrom] [float] NOT NULL,
[MeasureTo] [float] NOT NULL,
[Value] [smallint] NOT NULL,
[Timestamp] [datetime2](7) NOT NULL
FeatureId, MeasureFrom und MeasureTo definieren grundsätzlich ein Intervall und Rating ist der Wert dieses Intervalls. Beachten Sie, dass FeatureId tatsächlich auf reale Linien (Formen) aus einer anderen Tabelle verweist. In dieser Tabelle befinden sich derzeit ca. 250.000 Zeilen mit überlappenden Intervallen und verschiedenen Zeitstempeln (historische Aufzeichnungen). Unser Aggregationsprozess versucht, den neuesten Wert über alle Intervalle hinweg zu finden, sodass Intervalle basierend auf dem Zeitstempel gekürzt und verknüpft werden müssen und der zugehörige Wert beibehalten wird.
Da die direkte Abfrage langsam ist und viele Ressourcen beansprucht, dachten wir, wir müssten möglicherweise eine weitere Datenbank erstellen, in der die Ergebnisse dieser Aggregation gespeichert werden. Die Quelltabelle wird ständig aktualisiert (aber nicht zu oft, einmal in ein paar Tagen).
Was wäre der beste Weg, um diese Datenbank zu erstellen und die aggregierten Werte auf dem neuesten Stand zu halten? Ich kann mir vorstellen, Trigger oder geplante Aufgaben zu verwenden. Ich habe keine Erfahrung mit SSAS, aber wäre das besser geeignet?
Zu beachten ist, dass wir einige ähnliche Tabellen haben, in denen leicht unterschiedliche Werte gespeichert sind (einige mit mehr als einer Wertespalte) und daher der Grund für eine separate Datenbank anstelle einer anderen Tabelle in der Originaldatenbank.
Wie schnell würde die Abfrage dieser separaten Datenbank von der ursprünglichen Datenbank mithilfe datenbankübergreifender Verknüpfungen erfolgen?
Bearbeitet: Um zu demonstrieren, was unsere "Aggregation" bewirkt, hier einige Beispieldaten:
FeatureId | MeasureFrom | MeasureTo | Value | Timestamp
1 | 1 | 20 | 2 | 2015-01-01
1 | 5 | 15 | 3 | 2015-01-02
1 | 9 | 10 | 8 | 2015-01-03
Und das Ergebnis, das wir bekommen:
FeatureId | MeasureFrom | MeasureTo | Value | Timestamp
1 | 1 | 5 | 2 | 2015-01-01
1 | 5 | 9 | 3 | 2015-01-02
1 | 9 | 10 | 8 | 2015-01-03
1 | 10 | 15 | 3 | 2015-01-02
1 | 15 | 20 | 2 | 2015-01-01
Wie Sie sehen können, enthält das Ergebnis tatsächlich mehr Zeilen als die Originaldaten. Grundsätzlich benötigen wir den neuesten Wert an jedem Punkt innerhalb des Gebiets. Der letzte Wert wird basierend auf dem Wert in der Spalte Zeitstempel ermittelt. Wenn innerhalb von Intervallen eine Lücke besteht, sollte diese auf den resultierenden Datensatz übertragen werden.
Der Code ist tatsächlich in .NET geschrieben und ziemlich kompliziert. Der Algorithmus lautet wie folgt: Alle Daten für ein Merkmal von Interesse abrufen, die Datensätze nach absteigendem Zeitstempel sortieren, alle Datensätze in einer Schleife verarbeiten. Nehmen Sie das Intervall (MeasureFrom, MeasureTo) und schneiden Sie es mit dem Ergebnis, das Sie haben. Wenn Sie einen Teil erhalten, den Sie noch nicht haben, fügen Sie ihn dem Ergebnis hinzu. Fahren Sie mit dem nächsten Datensatz fort. Daten stellen Umfragen dar, die regelmäßig durchgeführt werden. Je weiter Sie in der Zeit gehen, desto mehr Daten werden weggeworfen, da Sie bereits einen neueren Wert für dasselbe Intervall haben.
Umfragen werden mit zufälligen Zeitstempeln geliefert, sodass nicht immer die neuesten eingehen. Der gleiche Vorgang wird dann auch für andere Funktionen wiederholt, da Sie möglicherweise daran interessiert sind, Werte für mehrere Funktionen gleichzeitig abzurufen. Und dies ist das Ergebnis, das die Leute oft abfragen würden.
Idealerweise möchten wir das Aggregationsergebnis so nah wie möglich an der Echtzeit halten.
Weitere Informationen zum erforderlichen Algorithmus finden Sie unter dem Link von @dnoeth (im Kommentar unten) http://sqlmag.com/sql-server/packing-intervals-priorities . Es löst ein ähnliches Problem mit dem Unterschied, Prioritäten anstelle von Zeitstempeln zu verwenden, und die beschriebene Lösung verwendet Funktionen aus SQL Server 2012.
quelle
Antworten:
Die Aggregattabelle kann wahrscheinlich in derselben Datenbank verbleiben. Sie können es jedoch auf einer separaten Dateigruppe und Festplatte erstellen.
Vollständige Aktualisierung einer neuen Aggregattabelle
Eine Möglichkeit, dies mit reinem SQL und Ihrem Beispiel zu tun:
Bei dieser wirklich kleinen Stichprobe bin ich mir nicht sicher, ob sie alle Ihre Bedürfnisse abdeckt. Es kann hilfreich sein, eine größere Stichprobe mit mehr Daten hinzuzufügen.
Es werden 4 Tabellenscans durchgeführt. Da Sie 250.000 Zeilen haben, ist die Leistung möglicherweise nicht so gut. Es ist wahrscheinlich besser, es in einem Stapel von X aufeinanderfolgenden FeatureIds auszuführen.
Dies kann mithilfe eines Jobs und eines SSIS-Pakets mit einem einzelnen Update oder einem Batch-Update erfolgen. Sie müssten zuerst die Aggregattabelle abschneiden.
Auslöser für jede neue Zeile in der Haupttabelle
Für neue Zeilen, die einen Trigger verwenden, kann diese Abfrage verwendet werden:
Sie müssen den neuen CTE durch die Werte der neu eingefügten Zeile im Trigger ersetzen und zum Zusammenführen mit der Aggregattabelle verwenden.
Geplante Aktualisierung neu hinzugefügter Zeilen
Wenn Sie eine Möglichkeit finden, eine Liste aller neu hinzugefügten Zeilen zur Haupttabelle seit der letzten Aktualisierung der Aggregattabelle abzurufen, können Sie einen Job alle x Minuten oder Stunden planen und nur das aktualisieren, was auf der Grundlage der letzten Daten erforderlich ist hinzugefügt.
Die Trigger-Abfrage funktioniert auch bei geplanten Updates.
Dies kann als geplanter Job und innerhalb eines SSIS-Pakets ausgeführt werden.
quelle
Das Lesen / Verknüpfen aus mehreren Datenbanken ist wahrscheinlich nicht schneller als das Belassen der Daten in einer Tabelle in der Primärdatenbank, es sei denn, die zweite Datenbank befindet sich auf einer separaten physischen Festplatte. Denken Sie daran, dass die "Kosten" die meiste Zeit in der Festplatten-E / A liegen. Um die Arbeit in diesem Fall zu beschleunigen, sollten Sie versuchen, die Festplatten-E / A zu verringern oder zu verteilen. Dies wird durch Erstellen von Indizes, Partitionieren der Tabellen auf verschiedene Datenträger oder Verschieben Ihrer Aggregattabelle auf einen anderen Datenträger oder eine andere Datenbank erreicht.
Es hört sich so an, als würden Sie dazu neigen, Dinge nach einem Zeitplan zu migrieren oder zu speichern. SSAS kann dies möglicherweise erreichen (ich weiß nicht), aber es kann schwierig sein, jemanden zu finden, der einigermaßen gut in SSAS ist. Auf der anderen Seite können Sie einen Job einfach über SSIS planen (dies ist möglicherweise das, was Sie gemeint haben; SSAS ist Analysis Services und arbeitet mit Cubes; SSIS ist Integration Services und dient eher zum Transformieren und Verschieben von Daten zwischen Quellen, z. B. zum Extrahieren von Tabellen oder Inhalte in eine CSV- oder Excel-Datei anzeigen.)
quelle