使用している場合、システムバージョン管理一時テーブル(SQL Serverの2016年新)が、この機能は大規模なリレーショナルデータウェアハウス内の寸法を変更ゆっくり処理するために使用されるクエリのオーサリングおよびパフォーマンスの意味は何ですか?
たとえば、列を含む100,000行のCustomer
ディメンションと、外部キー列Postal Code
を含む数十億行のSales
ファクトテーブルがあるとしCustomerID
ます。そして、「顧客の郵便番号別の2014年の総売上」をクエリしたいとします。簡略化されたDDLは次のようなものです(わかりやすくするために多くの列を省略しています)。
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
);
興味深いのは、顧客がその年に移動した可能性があるため、同じ顧客が異なる郵便番号を持っている可能性があることです。また、顧客が引っ越してから戻ってしまう可能性もあります。つまり、同じ郵便番号を持つ同じ顧客に対して複数の履歴レコードが存在する可能性があります。「郵便番号による販売」のクエリは、顧客の郵便番号が時間とともにどのように変化するかに関係なく、正しい結果を計算できるはずです。
テンポラルテーブルを使用して顧客ディメンション(たとえばSELECT * FROM Customer FOR SYSTEM_TIME FROM '2014-1-1' TO '2015-1-1'
)のみをクエリする方法は理解していますが、ファクトテーブルに最も正確かつ効率的に結合する方法がわかりません。
これはどのようにクエリする必要がありますか?
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
そして、このようなクエリを作成する際に注意すべきパフォーマンスの考慮事項は何ですか?