Самый быстрый способ расчета промежуточных итогов в SQL - PullRequest
0 голосов
/ 23 марта 2020

Я хочу вычислить промежуточную сумму в каждой строке моего запроса на выборку, чтобы я мог отфильтровать строки, возвращаемые на основе этой суммы. На мой взгляд, у меня есть только 2 варианта.

  1. Используйте over в операторе выбора и сделайте основной запрос подзапросом

Пример:

SELECT DocDate,
       Debit,
       RunningTotal
FROM
(
    SELECT T1.DocDate,
           T1.Debit,
           SUM(T1.Debit) OVER(ORDER BY T1.DocDate DESC) AS RunningTotal
        FROM Invoices T1
) AS T
WHERE RunningTotal < @CurrentBalance 
Join таблица сама с собой

Пример:

SELECT T1.DocDate,
       T1.Debit,
       SUM(T2.Debit) AS RunningTotal
FROM Invoices T1
JOIN Invoices T2 ON T1.DocDate <= T2.DocDate
GROUP BY T1.DocDate,
   T1.Debit
   HAVING SUM(T2.Debit) < @CurrentBalance
ORDER BY T1.DocDate DESC

Оба запроса возвращают абсолютно одинаковый результат. Тем не менее, с точки зрения производительности, какой будет рекомендуемый путь к go?

1 Ответ

3 голосов
/ 23 марта 2020

Если в вашей таблице так мало строк, что вы можете сосчитать их с одной стороны, встроенная функция окна будет работать быстрее.

Почему? Во-первых, он встроен и предназначен для этой цели.

Во-вторых, он фактически рассчитывает совокупную сумму. Таким образом, при вычислении 10-го значения он использует результат из 9-й кумулятивной суммы и просто добавляет к нему еще одно значение.

Подход join является особенно вопиющим способом выполнения вычислений. Если у вас есть 100 строк в таблице, то она расширяет таблицу до 100 * 99/2 строк (дать или взять) - и затем должна агрегировать более 100 строк. Вы можете видеть, что это только ухудшается, когда ваша таблица становится больше.

Тем не менее, если у вас есть три строки в таблице, вы можете обнаружить, что соединение работает лучше. Таков закон больших чисел: иногда удивительные вещи случаются при меньших числах.

...