Pregunta

Tengo un procedimiento almacenado que utiliza una vista para tirar de 6 promedios. La base de datos SQL es SQL Server 2000. Cuando lo ejecuto en el analizador de consultas, se tarda aproximadamente 9 segundos. ¿Qué puedo hacer para obtener un mejor rendimiento? Debería devolver las filas utilizando LINQ y determinar un promedio de esa manera? Va a ser más rápido?

Este es un ejemplo de mi sproc actual:

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

Además, quiero aclarar el punto de vista mencionado anteriormente. Dado que este es SQL Server 2000, no puede utilizar una vista indizada porque hace uso de una subconsulta. Supongo que esto puede ser reescrito para usar combinaciones. Sin embargo, la última vez que tomó una consulta y lo reescribió para utilizar une, faltaban datos (debido a que la consulta puede devolver un valor nulo que omita toda la fila).

¿Fue útil?

Solución

Yo recomendaría conseguir los datos en una tabla var en primer lugar, tal vez 2 mesa de Vars, 1 de 12 y 1 de 16 ProductID. A partir de estos VARs tabla, calcular los GVAs según sea necesario, y luego tose y regresó de los 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

Además, la creación de los índices correctos en la mesa, va a ayudar mucho.

Otros consejos

¿Cuál sería la cantidad de datos que salen de la base de datos del servidor sea si era no agregada, y el tiempo de hacer esa operación? La diferencia en el tamaño de los datos guiará si el tiempo de cálculo en el servidor se ve compensado por el tiempo de transferencia y el cálculo local.

También - mira que el uso DATEDIFF y el cambio que sea más fácil para que sea optimizable (tratar DateFullfilled> = SomeCalculatedDate1 en lugar de DATEDIFF) - revisar su plan de ejecución para asegurarse de que es capaz de utilizar una búsqueda de índice (mejor) o recorrido de índice (bueno) en lugar de un table_scan.

También, asegurarse de que hay un índice en CUSTOMERNUMBER, ProduceID, DateFulfilled.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top