Frage

Ich habe zwei Tabellen: Details und Summen dieser Details.

Einzelheiten (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 (ein Job muss veränderte Gesamtsummen neu berechnen, aber es verzögert). Wie Sie verstehen, ist die zweite Abfrage schneller und die Anzahl der gültigen Summen mehr als ungültige. Ich suche also nach einer kombinierten Abfrage, die gültige Gesamtzahl aus der zweiten Tabelle (Gesamtsummen) zurückgibt und mit der ersten langsamen Abfrage dynamisch neu berechnet wird. Mein Ziel wird also erreicht: Alle Summen sind gültig und die Zeit für die Reaktion 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 schnelle und hybride Lösung verglichen, ich habe 32% bis 68% (relative Abfragekosten). Wenn Sie eine kommentierte Variante sehen können, entspricht sie 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, um die Summen neu zu berechnen, und dieser Prozess wird nicht mit Abfragebestimmungen synchronisiert. InvalidOrters -Tabellen sind ein wenig, das Datensätze speichern, um zu wissen, dass die Summen ungültig sind (um neu berechnet zu werden)

LÖSUNG

Indexierte Ansichten sind die beste Wahl. Beachten Sie auf SQL Server Edition (Noexpand Hinweis für nicht eingebildete Ausgaben) und bereit sein Erstellen Sie einige Datenbankobjekte neu (SET ANSI_NULLS ON, SET QUOTED_IDENTIFIER ON) Um mit indizierten Ansichten auf der Client -Seite zu beginnen.

War es hilfreich?

Lösung

Ich kann nicht verstehen, warum Sie nicht im Laufe der Fliege aggregieren können und warum es so langsam ist. Ist die "gültige" Idee eine Problemumgehung, die sich mit der Verzögerung der Auftragsabrechnungen oder eines Geschäftsprozesses befasst

Beide Ideen verwerfen die Tabelle Invalid Order, die eine Problemumgehung für die schlechte Indexierung darstellt.

  • Vorschlag 1:

Erstellen Sie eine berechnete Spalte

ALTER TABLE dbo.Order ADD PriceXQuantity AS Price * Quantity PERSISTED

Fügen Sie einen Index hinzu

CREATE INDEX IX_Totals ON dbo.Order (OrderID) INCLUDE Quantity, PriceXQuantity)

Schau was passiert

  • Vorschlag 2:

Verwenden Sie eine indizierte Ansicht

CREATE VIEW OrderTotals
WITH SCHEMABINDING
AS
select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
  , COUNT_BIG(*) AS Dummy
from dbo.Order r
group by r.OrderId
GO
CREATE UNIQUE CLUSTERED INDEX IXCU_OrderTotals ON OrderTotals (OrderId9
GO

Sie können auch hier die Computerspalte verwenden

Andere Tipps

Wenn die Kosten nicht zu hoch wären, könnten Sie in Betracht ziehen, das zu bewegen IsValid Flagge in die Detail Tabelle und Index es? Dies würde Ihre Transaktionen verlangsamen, aber die Abfrageleistung als (vermutlich) groß verbessern Detail Tisch würde in einem großen zugreifen range scan

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit dba.stackexchange
scroll top