Используя T-SQL AVG или взяв Среднее после результатов, возвращенных с помощью LINQ - PullRequest
0 голосов
/ 18 ноября 2009

У меня есть хранимая процедура, которая использует представление для получения 6 средних. База данных SQL - это SQL Server 2000. Когда я запускаю ее в анализаторе запросов, это занимает примерно 9 секунд. Что я могу сделать, чтобы получить лучшую производительность? Должен ли я вернуть строки с помощью LINQ и определить среднее значение таким образом? Это будет быстрее?

Вот пример моего текущего sproc:

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

Кроме того, позвольте мне прояснить мнение, упомянутое выше. Поскольку это SQL Server 2000, я не могу использовать индексированное представление, потому что оно использует подзапрос. Я полагаю, это можно переписать, чтобы использовать соединения. Однако в последний раз, когда мы брали запрос и переписывали его для использования объединений, данные отсутствовали (поскольку подзапрос может возвращать нулевое значение, которое пропустило бы всю строку).

Ответы [ 2 ]

2 голосов
/ 18 ноября 2009

Каков объем данных, покидающих сервер базы данных, если он будет неагрегирован, и как долго будет выполняться эта операция? Разница в размере данных определяет, будет ли время вычислений на сервере перевешиваться временем переноса и локальным вычислением.

Кроме того - посмотрите на это DATEDIFF использование и измените его, чтобы было легче сделать его оптимизируемым (попробуйте DateFullfilled> = SomeCalculatedDate1 вместо DATEDIFF) - проверьте план выполнения, чтобы убедиться, что он может использовать поиск по индексу (лучше) или индексное сканирование (хорошо) вместо table_scan.

Также убедитесь, что есть индекс для CustomerNumber, ProduceID, DateFulfilled.

1 голос
/ 18 ноября 2009

Я бы рекомендовал сначала получить данные в таблицу var, может быть, 2 таблицы, 1 для 12 и 1 для 16 ProductID. Из этих табличных переменных вычислите средние значения по мере необходимости, а затем верните tose из 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

Также очень поможет создание правильных индексов на таблице.

...