CASE против нескольких запросов UPDATE для больших наборов данных - производительность - PullRequest
11 голосов
/ 26 марта 2012

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

Использование оператора CASE или отдельных запросов на обновление?

CASE Пример:

UPDATE tbl_name SET field_name = 
CASE
    WHEN condition_1 THEN 'Blah'
    WHEN condition_2 THEN 'Foo'
    WHEN condition_x THEN 123
    ELSE 'bar'
END AS value

Пример отдельного запроса:

UPDATE tbl_name SET field_name = 'Blah' WHERE field_name = condition_1
UPDATE tbl_name SET field_name = 'Foo' WHERE field_name = condition_2
UPDATE tbl_name SET field_name = 123 WHERE field_name = condition_x
UPDATE tbl_name SET field_name = 'bar' WHERE field_name = condition_y

ПРИМЕЧАНИЕ. Будет обновлено около 300 000 записей, а оператор CASE будет иметь около 10 000 условий WHEN.При использовании отдельных запросов это также около 10000

Ответы [ 3 ]

15 голосов
/ 26 марта 2012

Версия CASE.

Это потому, что есть большая вероятность, что вы изменяете одну и ту же строку более одного раза с отдельными утверждениями. Если в строке 10 есть и condition_1, и condition_y, тогда ее нужно будет прочитать и изменить дважды. Если у вас есть кластеризованный индекс, это означает, что два кластеризованных индекса обновляются поверх других полей, которые были изменены.

Если вы можете сделать это как один оператор, каждая строка будет прочитана только один раз, и она должна выполняться намного быстрее.

Я изменил аналогичный процесс около года назад, когда использовались десятки UPDATE последовательных операторов, чтобы использовать начиная с UPDATE с CASE, а время обработки сократилось примерно на 80%.

0 голосов
/ 27 марта 2012

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

Таким образом, ваш оператор обновления становится (более или менее):

UPDATE tbl_name SET field_name = COALESCE((SELECT value FROM temp_tbl WHERE tbl_name.conditional_field = temp_tbl.condition_value), field_name),
    field_name2 = COALESCE((SELECT value FROM temp_tbl2 WHERE tbl_name.conditional_field2 = temp_tbl2.condition_value), field_name2)

и так далее ..

Это должно обеспечить хорошую производительность при одновременном масштабировании больших объемов обновлений.

0 голосов
/ 26 марта 2012

Мне кажется логичным, что при первом варианте SQL Server будет проходить таблицу только один раз, и для каждой строки он будет оценивать условие.

На втором он должен будет пройти всю таблицу 4 раза

Итак, для таблицы с 1000 строками, в первом варианте в лучшем случае речь идет о 1000 оценках, а в худшем - 3000. На втором у нас всегда будет 4000 оценок

Таким образом, вариант 1 будет быстрее.

...