Yavaş Değişen Boyutlar için SQL Server 2016 sistem sürümündeki geçici tabloları kullanarak stratejileri sorgulama


17

Bir kullanırken sistem sürümü belirlenmiş zamansal tablo (SQL Server 2016 yılında yeni), bu özellik büyük bir ilişkisel veri ambarında Boyutları değiştirme yavaşça işlemek için kullanılan sorgu yazma ve performans etkileri nelerdir?

Örneğin, Customerbir Postal Codesütun ile 100.000 satırlık bir boyutum ve yabancı anahtar sütunlu Salesbir milyar dolarlık bir olgu tablosum olduğunu varsayalım CustomerID. "Müşterinin posta koduna göre toplam 2014 satışını" sorgulamak istediğimi varsayalım. Basitleştirilmiş DDL şu şekildedir (açıklık için birçok sütunu atlayarak):

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
);

İlginç olan, müşterilerin yıl içinde hareket etmiş olmalarıdır, böylece aynı müşterinin farklı posta kodları olabilir. Ve bir müşterinin uzaklaşıp sonra geri taşınması bile uzaktan mümkündür, yani aynı müşteri için aynı posta koduna sahip birden fazla geçmiş kaydı olabilir! "Posta koduna göre satışlar" sorgum, müşterilerin posta kodlarının zaman içinde nasıl değiştiğinden bağımsız olarak doğru sonuçları hesaplayabilmelidir.

Geçici tabloları yalnızca müşteri boyutunu sorgulamak için nasıl kullanacağımı anlıyorum (örneğin SELECT * FROM Customer FOR SYSTEM_TIME FROM '2014-1-1' TO '2015-1-1'), ancak olgu tablosuna en doğru ve verimli bir şekilde nasıl katılacağından emin değilim.

Sorgulamam bu mu?

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

Ve böyle sorgular yaparken dikkat etmem gereken performans faktörleri nelerdir?

Yanıtlar:


1

Bence, durumunuzda müşteri başına posta kodu mutasyonlarının sorgulama sayısını izole etmek için türetilmiş bir tablo gereklidir:

SELECT c.postalcode 
, sum(s.SaleAmount) SaleAmount
, count(postcode_mutations.customerid) as CntCustomerChangedPostCode   
FROM dbo.Sale s
JOIN dbo.Customer c on s.customerid = c.customerid

LEFT JOIN (
SELECT 
    CustomerID
FROM [dbo].[Customer]
FOR SYSTEM_TIME FROM '20140101' TO '20150101'
GROUP BY CustomerID
HAVING COUNT(DISTINCT PostalCode) > 1
) postcode_mutations on s.customerid = postcode_mutations.customerid

WHERE s.SaleDateTime >= '2014-1-1' AND s.SaleDateTime < '2015-1-1'
GROUP BY c.PostalCode

upd: Sorgunun DWH / Analytics senaryoları sunması gerektiğinden, sütun deposu dizine ekleme kontrol etme seçeneğidir. Ayrıca daha önce 10 milyon satırlık tablo için bazı kriterler yaptım .


Müşteri başına değişiklik sayısını saymak neden gereklidir? Yıl içinde posta kodunu değiştiren müşteriler sorguya karmaşıklık katıyor, ancak aslında bu değişikliklerin raporlanması gerekmiyor gibi görünüyor.
Justin Grant

@JustinGrant Değişiklik sayısı, bu mutasyonların geçmiş verilerden nasıl alınabileceğini göstermektir. Ancak, bu satırları dün eklediniz: "Posta koduna göre satışlar" sorgum, müşterilerin posta kodlarının zaman içinde nasıl değiştiğine bakılmaksızın doğru sonuçları hesaplayabilmelidir. Talebi daha net hale getirin. Bu durumda, SYSTEM_TIME her iki tablo için de aynı şekilde ayarlanmalıdır. ve iki yol vardır: 1) Yoksun tabloları kullanın ve her iki tablo için system_time uygulayın. 2) Veya birleştirme tutan bir görünüm oluşturun ve görünümü sorgulamak için SYSTEM_TIME uygulayın
Alexandr Volok
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.