Domanda

Ho due tabelle: i dettagli e totali di questi dettagli.

Dettagli ( soluzione lento ):

select 
    OrderId             =   r.OrderId                   
  , TotalQty            =   SUM(r.Quantity)
  , TotalGrossConsid    =   SUM(r.Price * r.Quantity)
from dbo.Order r
group by r.OrderId

Totali ( soluzione rapida ):

select 
    t.OrderId                           
  , t.TotalQty          
  , t.TotalGrossConsid  
  , t.IsValid
from dbo.OrderTotal t

A volte i totali diventare valido (qualche lavoro deve ricalcolare i totali cambiato, ma ritarda). Come si capisce la seconda query è più veloce e il numero dei totali validi è più che quelli non validi. Così sto cercando una query combinata che restituisce totali valide della seconda tabella (totali) e ritorna ricalcolati in modo dinamico i totali utilizzando la prima query lenta. Quindi il mio obiettivo sarà raggiunto:. Tutti i totali sono validi e il tempo di risposta è più veloce quindi piena ricalcolo

Ecco il mio tentativo ( soluzione ibrida ):

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)

Ho confrontato la soluzione rapida e un sistema ibrido, ho ottenuto 32% al 68% (costi di query relative). Se si può vedere commentato variante è uguale a 1% a 99% (peccato). E 'possibile migliorare questa ricerca?

AGGIUNTO

@gbn:

Valid  =  case when i.OrderId is null then 1 else 0 end
...
dbo.OrderTotal t  left join dbo.InvalidOrders i

Sì, ho un lavoro per ricalcolare i totali e questo processo non è sincronizzata con richieste di query. InvalidOrders tabelle è un po 'quello che i record dei negozi di sapere che i totali non è valido (per essere ricalcolato)

SOLUTION

viste indicizzate sono la scelta migliore. Essere consapevoli sulla edizione di SQL Server ( NOEXPAND suggerimento edizioni non-impresa) ed essere pronti a ricreare alcuni oggetti di database (SET ANSI_NULLS ON, SET QUOTED_IDENTIFIER ON) per iniziare a utilizzare viste indicizzate sul lato client.

È stato utile?

Soluzione

Non riesco a capire perché non si può aggregare al volo e perché è così lento. è l'idea "Valido" una soluzione per affrontare il ritardo di OrderTotals o di qualche processo di business

Entrambe queste idee scartare tabella InvalidOrder che è una soluzione per scarsa indicizzazione.

  • Suggerimento 1:

Creare una colonna calcolata

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

Aggiungi un indice

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

vedere cosa succede

  • Suggerimento 2:

Usa una vista indicizzata

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

È possibile utilizzare la colonna calcolata anche qui

Altri suggerimenti

Se il costo non sarebbe troppo alto, si potrebbe prevedere il passaggio della bandiera IsValid nella tabella Detail e indicizzarlo? Ciò rallenterebbe le transazioni, ma migliorare le prestazioni delle query come (presumibilmente) grande tavolo Detail sarebbe possibile accedere in un unico grande range scan

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top