Використовуючи тимчасову таблицю з версією системи (нову в SQL Server 2016), які наслідки щодо створення запитів та продуктивності, коли ця функція використовується для обробки повільних змін розмірів у великому сховищі реляційних даних?
Наприклад, припустимо, що у мене Customer
розмір 100000 рядків зі 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
І які міркування щодо ефективності, на які я повинен слідкувати, коли роблю такі запити?