Welche Auswirkungen haben die Erstellung von Abfragen und die Leistung bei der Verwendung einer vom System versionierten temporalen Tabelle (neu in SQL Server 2016), wenn diese Funktion zum langsamen Ändern von Dimensionen in einem großen relationalen Data Warehouse verwendet wird?
Angenommen, ich habe eine Customer
Dimension von 100.000 Zeilen mit einer Postal Code
Spalte und eine Sales
Faktentabelle mit mehreren Milliarden Zeilen mit einer CustomerID
Fremdschlüsselspalte. Angenommen, ich möchte "Gesamtumsatz 2014 nach Postleitzahl des Kunden" abfragen. Die vereinfachte DDL sieht folgendermaßen aus (der Übersichtlichkeit halber werden viele Spalten weggelassen):
CREATE TABLE Customer
(
CustomerID int identity (1,1) NOT NULL PRIMARY KEY CLUSTERED,
PostalCode varchar(50) NOT NULL,
SysStartTime datetime2 GENERATED ALWAYS AS ROW START NOT NULL,
SysEndTime datetime2 GENERATED ALWAYS AS ROW END NOT NULL,
PERIOD FOR SYSTEM_TIME (SysStartTime, SysEndTime)
)
WITH (SYSTEM_VERSIONING = ON);
CREATE TABLE Sale
(
SaleId int identity(1,1) NOT NULL PRIMARY KEY CLUSTERED,
SaleDateTime datetime2 NOT NULL,
CustomerId int NOT NULL FOREIGN KEY REFERENCES Customer(CustomerID),
SaleAmount decimal(10,2) NOT NULL
);
Interessant wird, dass Kunden möglicherweise im Laufe des Jahres umgezogen sind, sodass derselbe Kunde möglicherweise unterschiedliche Postleitzahlen hat. Und es ist sogar aus der Ferne möglich, dass ein Kunde weggezogen ist und dann zurückgezogen ist, was bedeutet, dass es mehrere Verlaufsdatensätze für denselben Kunden mit derselben Postleitzahl geben kann! Meine Abfrage "Umsatz nach Postleitzahl" sollte in der Lage sein, korrekte Ergebnisse zu berechnen, unabhängig davon, wie sich die Postleitzahlen der Kunden im Laufe der Zeit ändern.
Ich verstehe, wie Temporaltabellen verwendet werden, um nur die Kundendimension abzufragen (z. B. SELECT * FROM Customer FOR SYSTEM_TIME FROM '2014-1-1' TO '2015-1-1'
), bin mir jedoch nicht sicher, wie ich die Faktentabelle am genauesten und effizientesten verknüpfen kann.
Soll ich das so abfragen?
SELECT c.PostalCode, sum(s.SaleAmount) SaleAmount
FROM Customer c FOR SYSTEM_TIME FROM '2014-1-1' TO '2015-1-1'
JOIN Sale s ON s.CustomerId = c.CustomerId
WHERE s.SaleDateTime >= '2014-1-1' AND s.SaleDateTime < '2015-1-1'
AND c.SysStartTime >= s.SaleDateTime
AND c.SysEndTime < s.SaleDateTime
GROUP BY c.PostalCode
Und auf welche Leistungsaspekte sollte ich bei solchen Abfragen achten?
quelle