Ich habe zwei Tabellen: Details und Summen dieser Details.
Details ( langsame Lösung ):
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId
Summen ( schnelle Lösung ):
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
Manchmal werden Summen ungültig (einige Jobs müssen geänderte Summen neu berechnen, aber es verzögert sich). Wie Sie verstehen, ist die zweite Abfrage schneller und die Anzahl der gültigen Summen ist höher als die der ungültigen. Daher suche ich nach einer kombinierten Abfrage, die gültige Summen aus der zweiten Tabelle (Summen) zurückgibt und mithilfe der ersten langsamen Abfrage dynamisch neu berechnete Summen zurückgibt. Damit ist mein Ziel erreicht: Alle Summen sind gültig und die Reaktionszeit ist schneller als die vollständige Neuberechnung.
Hier ist mein Versuch ( Hybridlösung ):
with fast_static(OrderId, TotalQty, TotalGrossConsid, IsValid)
as
(
select
t.OrderId
, t.TotalQty
, t.TotalGrossConsid
, t.IsValid
from dbo.OrderTotal t
)
, slow_dynamic(OrderId, TotalQty, TotalGrossConsid)
(
select
OrderId = r.OrderId
, TotalQty = SUM(r.Quantity)
, TotalGrossConsid = SUM(r.Price * r.Quantity)
from dbo.Order r
)
select
OrderId, TotalQty, TotalGrossConsid
from fast_static
where IsValid = 1
union all
select
OrderId, TotalQty, TotalGrossConsid
from slow_dynamic s
--inner join fast_static ff
--on ff.OrderId = s.OrderId
where --ff.Valid = 0 -- too slow!!!
s.OrderId in (select OrderId from fast_static f where f.Valid = 0)
Ich habe die Fast-Lösung mit der Hybrid-Lösung verglichen und 32% bis 68% (relative Abfragekosten) erhalten. Wenn Sie eine kommentierte Variante sehen können, entspricht dies 1% bis 99% (schade). Ist es möglich, diese Abfrage zu verbessern?
HINZUGEFÜGT
@gbn:
Valid = case when i.OrderId is null then 1 else 0 end
...
dbo.OrderTotal t left join dbo.InvalidOrders i
Ja, ich habe einen Job zum Neuberechnen von Summen und dieser Prozess ist nicht mit Abfrageanforderungen synchronisiert. InvalidOrders-Tabellen sind kleine Tabellen, in denen Datensätze gespeichert werden, um zu wissen, dass Summen ungültig sind (neu zu berechnen).
LÖSUNG
Indizierte Ansichten sind die beste Wahl. Beachten Sie die SQL Server-Edition ( Noexpand-Hinweis für Nicht-Enterprise-Editionen) und erstellen Sie einige Datenbankobjekte ( SET ANSI_NULLS ON, SET QUOTED_IDENTIFIER ON
) neu, um indizierte Ansichten auf der Clientseite zu verwenden.
details
. Dies