Pergunta

Eu tenho um procedimento armazenado que usa uma visão para extrair 6 médias. O banco de dados SQL é o SQL Server 2000. Quando o executo no analisador de consultas, leva cerca de 9 segundos. O que posso fazer para obter melhor desempenho? Devo devolver as linhas usando o LINQ e determinar uma média dessa maneira? Será mais rápido?

Aqui está um exemplo do meu sproc atual:

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

Além disso, deixe -me esclarecer a visão mencionada acima. Como este é o SQL Server 2000, não posso usar uma visualização indexada porque ele usa uma subconsulta. Suponho que isso possa ser reescrito para usar junções. No entanto, a última vez que pegamos uma consulta e a reescrevemos para usar junções, os dados estavam faltando (porque a subconsulta pode retornar um valor nulo que omitiria a linha inteira).

Foi útil?

Solução

Eu recomendaria colocar os dados em uma tabela VAR primeiro, talvez 2 vars de tabela, 1 para 12 e 1 para 16 ProductId. A partir dessas vars de tabela, calcule os AVGs conforme necessário e retorne a Tose do 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

Além disso, criar os índices corretos na tabela ajudará muito.

Outras dicas

Qual seria a quantidade de dados que deixariam o servidor de banco de dados se não for agregado e por quanto tempo fazer essa operação? A diferença no tamanho dos dados orientará se o tempo de cálculo no servidor é superado pelo tempo de transferência e pelo cálculo local.

Além disso - olhe para isso DATEDIFF Uso e altere -o para ser mais fácil torná -lo otimizável (tente datefullFilled> = SomecalCulatedDate1 em vez de DATEDIFF) - Revise seu plano de execução para garantir que ele seja capaz de usar um índice procurar (melhor) ou digitalização de índice (boa) em vez de um tabela_scan.

Além disso, verifique se há um índice no CustomerNumber, ProductId, Datefilless.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top