Быстрое вычисление промежуточных итогов на сервере sql с использованием заданных операций - PullRequest
1 голос
/ 11 августа 2011

У меня есть некоторые данные, которые выглядят так:

+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 30           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 50           |
| 7 | 6      | 2           | 15            | 50           |
| 8 | 7      | 2           | 5             | 50           |
| 9 | 8      | 2           | 5             | 50           |
+---+--------+-------------+---------------+--------------+

И я преобразую это так:

+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 20           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 45           |
| 7 | 6      | 2           | 15            | 45           |
| 8 | 7      | 2           | 5             | 30           |
| 9 | 8      | 2           | 5             | 25           |
+---+--------+-------------+---------------+--------------+

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

Я сейчас использую курсор, потому что он быстрее, чем другие решения, которые я пробовал (cte, треугольное соединение, перекрестное применение). Мое решение с курсором сохраняет промежуточный итог, который сбрасывается в ноль для каждого нового параметра disid_id, увеличивает его на избыточный вес, выполняет обновления при необходимости и запускает примерно за 40 секунд. Другие решения, которые я пробовал, заняли где-то 3-5 минут, и мне интересно, есть ли относительно эффективный способ сделать это с помощью операций на основе множеств?

Ответы [ 3 ]

2 голосов
/ 11 августа 2011

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

1 голос
/ 11 августа 2011

Другое решение, которое вы, вероятно, уже попробовали, - это сделать что-то вроде найденных ответов здесь

Если вы не используете Oracle, который имеет приличные агрегаты для кумулятивной суммы, вам лучше использовать курсор. В лучшем случае вам придется снова присоединиться к таблице или использовать другие методы для выполнения операции O (n). В общем, решение, основанное на множестве, для таких проблем является грязным или действительно грязным.

0 голосов
/ 11 августа 2011

«предыдущие строки» подразумевают порядок. так что нет - там нет операций на основе множества.

Oracle LEAD и LAG созданы для этого, но SQL Server вынуждает вас к треугольным соединениям ... которые, я полагаю, вы исследовали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...