Aşağıdaki tablo yapısına sahip olduğunuzu düşünün:
LogId | ProductId | FromPositionId | ToPositionId | Date | Quantity
-----------------------------------------------------------------------------------
1 | 123 | 0 | 10002 | 2018-01-01 08:10:22 | 5
2 | 123 | 0 | 10003 | 2018-01-03 15:15:10 | 9
3 | 123 | 10002 | 10004 | 2018-01-07 21:08:56 | 3
4 | 123 | 10004 | 0 | 2018-02-09 10:03:23 | 1
FromPositionId
ve ToPositionId
hisse senedi pozisyonlarıdır. Örneğin bazı pozisyon kimlikleri özel bir anlama sahiptir 0
. Bir olaydan veya bir olay, 0
hisse senedinin yaratıldığı veya kaldırıldığı anlamına gelir. Gönderen 0
stoktan olabilir ve 0
sevk edilen bir sipariş olabilir.
Bu tablo şu anda yaklaşık 5.5 milyon satır içermektedir. Her ürün için stok değerini hesaplıyoruz ve şuna benzer bir sorgu kullanarak bir çizelgede önbellek tablosuna yerleştiriyoruz:
WITH t AS
(
SELECT ToPositionId AS PositionId, SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY ToPositionId, ProductId
UNION
SELECT FromPositionId AS PositionId, -SUM(Quantity) AS Quantity, ProductId
FROM ProductPositionLog
GROUP BY FromPositionId, ProductId
)
SELECT t.ProductId, t.PositionId, SUM(t.Quantity) AS Quantity
FROM t
WHERE NOT t.PositionId = 0
GROUP BY t.ProductId, t.PositionId
HAVING SUM(t.Quantity) > 0
Bu makul bir sürede (yaklaşık 20 saniye) tamamlansa da, bunun hisse senedi değerlerini hesaplamanın oldukça verimsiz bir yolu olduğunu hissediyorum. INSERT
Bu tabloda nadiren başka bir şey yapmıyoruz , ancak bazen bu satırları oluşturan kişilerin hatalarından dolayı içeri girip miktarı ayarlıyoruz veya bir satırı manuel olarak kaldırıyoruz.
Ayrı bir tabloda "kontrol noktaları" oluşturma, belirli bir zamana kadar değeri hesaplama ve hisse senedi miktarı önbellek tabloyu oluştururken başlangıç değeri olarak kullanma fikri vardı:
ProductId | PositionId | Date | Quantity
-------------------------------------------------------
123 | 10002 | 2018-01-07 21:08:56 | 2
Bazen satırları değiştirmemiz bunun için bir sorun teşkil eder, bu durumda değiştirdiğimiz günlük satırından sonra oluşturulan tüm kontrol noktalarını kaldırmayı da unutmamalıyız. Bu, şimdiye kadar kontrol noktalarını hesaplamamakla çözülebilir, ancak şimdiki ve son kontrol noktası arasında bir ay bırakın (çok nadiren değişiklikler yapıyoruz).
Bazen satırları değiştirmemiz gerektiğinden kaçınmak zordur ve bunu hala yapmak istiyorum, bu yapıda gösterilmiyor, ancak günlük olayları bazen diğer tablolardaki diğer kayıtlara bağlı ve başka bir günlük satırı ekleniyor doğru miktarı elde etmek bazen mümkün değildir.
Günlük tablosu, tahmin edebileceğiniz gibi, oldukça hızlı büyüyor ve hesaplama zamanı sadece zamanla artacak.
Soruma göre, bunu nasıl çözerdiniz? Mevcut hisse senedi değerini hesaplamanın daha verimli bir yolu var mı? Kontrol noktaları fikrim iyi mi?
SQL Server 2014 Web (12.0.5511) çalıştırıyoruz
Uygulama planı: https://www.brentozar.com/pastetheplan/?id=Bk8gyc68Q
Aslında yukarıdaki yanlış yürütme süresini verdim, 20'ler önbelleğin tam güncellemesinin aldığı zamandı. Bu sorgunun çalışması yaklaşık 6-10 saniye sürer (bu sorgu planını oluşturduğumda 8 saniye). Bu sorguda orijinal soruda yer almayan bir de birleştirme var.