Domanda

Ho una stored procedure che utilizza al fine di tirare 6 medie. Il database SQL è SQL Server 2000. Quando eseguo in Query Analyzer, ci vogliono circa 9 secondi. Che cosa posso fare per ottenere prestazioni migliori? Devo restituire le righe utilizzando LINQ e determinare una media in questo modo? Sarà più veloce?

Ecco un esempio della mia sproc corrente:

create procedure [TestAvg]
(
    @CustomerNumber int
)
as

select
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 7 and CustomerNumber = @CustomerNumber) as P12D7,
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 30 and CustomerNumber = @CustomerNumber) as P12D30,
(select AVG(OrderTime) from OrderDetails where ProductID = 12 and DateDiff(day, DateFulfilled, GetDate()) <= 90 and CustomerNumber = @CustomerNumber) as P12D90,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 7 and CustomerNumber = @CustomerNumber) as P16D7,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 30 and CustomerNumber = @CustomerNumber) as P16D30,
(select AVG(OrderTime) from OrderDetails where ProductID = 16 and DateDiff(day, DateFulfilled, GetDate()) <= 90 and CustomerNumber = @CustomerNumber) as P16D90

Inoltre, vorrei chiarire la vista di cui sopra. Poiché si tratta di SQL Server 2000, non posso usare una vista indicizzata perché utilizza una subquery. Suppongo che questo può essere riscritto per utilizzare join. Tuttavia, l'ultima volta che abbiamo preso una query e riscrisse da usare unisce, i dati mancava (perché il subquery può restituire un valore null che omettere l'intera riga).

È stato utile?

Soluzione

Lo raccomando ottenere i dati in una tabella var prima, forse 2 tavolo Vars, 1 per 12 e 1 per 16 ProductID. Da queste Vars tabella, calcolare le avgs come richiesto, e poi tornare tose dal sp.

DECLARE @OrderDetails12 TABLE(
        DateFulfilled DATETIME,
        OrderTime FLOAT
)

INSERT INTO @OrderDetails12
SELECT  DateFulfilled,
        OrderTime
FROM    OrderDetails
WHERE   ProductID = 12
AND     DateDiff(day, DateFulfilled, GetDate()) <= 90
and CustomerNumber = @CustomerNumber

DECLARE @OrderDetails16 TABLE(
        DateFulfilled DATETIME,
        OrderTime FLOAT
)

INSERT INTO @OrderDetails16
SELECT  DateFulfilled,
        OrderTime
FROM    OrderDetails
WHERE   ProductID = 16
AND     DateDiff(day, DateFulfilled, GetDate()) <= 90
and CustomerNumber = @CustomerNumber

Inoltre, la creazione degli indici corretti sul tavolo, sarà di grande aiuto.

Altri suggerimenti

Cosa sarebbe la quantità di dati che lasciano il server di database sia se fosse non conglobati, e per quanto tempo per fare questa operazione? La differenza nella dimensione dei dati guiderà se il tempo di calcolo sul server viene superato dal tempo di trasferimento e il calcolo locale.

Inoltre - guarda che l'utilizzo DATEDIFF e cambiare per essere più facile da fare è ottimizzabile (provare DateFullfilled> = SomeCalculatedDate1 invece di DATEDIFF) - rivedere il piano di esecuzione per assicurarsi che sia in grado di utilizzare un indice cercare (migliore) o indice di scansione (buono) invece di un table_scan.

Inoltre, assicurarsi che ci sia un indice su CustomerNumber, ProduceID, DateFulfilled.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top