2012-05-31 6 views
5

Я пишу большой скрипт с полными операциями обновления, которые будут выполняться ежедневно. Некоторые из этих обновлений будут влиять на другие строки.Производительность SQL Server - IF Select + Update vs Update

Я считаю, что заявления обновления, которые ничего не влияют на это не очень хорошая практика, но мой вопрос:

  • Как сильно это может повлиять на производительность ?? Разве это совсем не так, как при выборе операторов выбора и обновлении, только если вы выбираете что-то?

Спасибо, Тьягу

+1

Это зависит от того, насколько сложна ваша фраза 'WHERE'. Оператор 'UPDATE' должен сначала выяснить, какие строки обновить, или нет. Это может включать сканирование таблицы, если вам не хватает правильных индексов на этой таблице. Как всегда: ** проверить ** и посмотреть, насколько это плохо. Конечно, было бы лучше определить только те строки, которые действительно нуждаются в обновлении, а затем обновить только те. Но сколько усилий нужно для определения этих строк? –

+0

Усилия будут включать беспорядок с табличными переменными, а не только один или два ... Я говорю о 20 операциях обновления, выполняющихся вместе в скрипте и обновляющих разные таблицы. С точки зрения усилий по развитию было бы гораздо больше, чем просто разрабатывать заявления об обновлении. Что касается предложений where в обновлении, то большинство из них имеют одно или два внутренних соединения в большинстве и простых «равно null» или «<> 0», где клаузулы. –

ответ

1

Это зависит от того, как вы делаете обновление. Если вы обновляете с помощью присоединяемого синтаксиса (то есть)

UPDATE targetTable 
FROM targetTable INNER JOIN sourceTable 

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

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

UPDATE targetTable SET column = column 

... уволит триггер, который был определен на UPDATE. Я не на 100% на это, но я считаю, что это также делает его в журнале транзакций, потому что его необходимо поддерживать, чтобы резервные копии журнальных хвостов и цели зеркалирования могли полностью объединить последовательность событий.

+0

Я сделаю дальнейшие исследования о триггерной теме, хорошая точка там! Но я не ожидаю много триггеров на этих таблицах. –

1

Если вы имеете в виду, чтобы спросить, есть ли разница между UPDATE … WHERE condition И SELECT … WHERE the_same_condition + UPDATE … WHERE the_same_condition с точки зрения производительности, то я предпочел бы ожидать, что последний будет менее эффективным, чем прежний. Будь то UPDATE или SELECT, строки все равно должны быть вычислены, и с предварительным SELECT … WHERE … их нужно было бы разобрать дважды, если бы был хит.

Но @Matt Whitfield has got a point о триггерах. Если есть триггер при обновлении, он будет срабатывать независимо от того, обновлены ли какие-либо строки. И если есть что-то, то триггер делает, даже если нет обновленных строк (и вы хотели бы этого избежать), то либо перепишите свой триггер, либо, да, перейдите с подходом SELECT + UPDATE.

+0

Да, это был мой вопрос, и из комментариев, которые я получил здесь, я очень хорошо поддерживаю подход Update. Просто проверяя, какие таблицы имеют триггеры при обновлении и видят поведение на них. Спасибо! –

3

Прежде всего, SELECT, за которым следует UPDATE, почти всегда является недопустимым при параллелизме. Если ничего не выполняется при уровне изоляции SERIALIZABLE, нет гарантии, что строки не меняют между SELECT и UPDATE.

Во-вторых, для случаев, когда являются строк для обновления, стоимость SELECT + UPDATE по определению выше, чем просто ОБНОВЛЕНИЕ.

И последнее, для случая, когда не являются строк, чтобы обновить стоимость их размещения с помощью UPDATE, часто совпадают с затратами на их поиск по SELECT, поэтому вы ничего не выиграли. Я говорю «часто», а не «всегда», потому что оптимизатор запросов может рассматривать разные стратегии обновления и выбора, а проверка обновлений происходит в соответствии с разными правилами блокировки (параллелизма), чем сканирование для чтения.

Что может иметь смысл - иметь очень дешевый SELECT, который может избежать дорогого ОБНОВЛЕНИЯ, даже если он не на 100% точнее. Условия между SELECT и UPDATE могут сильно различаться. Пока вы не получаете никаких ложных негативов (SELECT говорит, что не должно быть никаких строк, но UPDATE бы нашел строку, если бы она была запущена) и количество ложных (SELECT говорит, что есть строки, но более точная/дорогая проверка UPDATE на самом деле не находит).

В конечном счете это проблема оптимизации, и все вопросы по оптимизации начинаются с , измеряя. Сначала найдите дорогой UPDATE, а затем начните изменять.