Плюсы и минусы проверки, существует ли значение для уникального столбца или пусть db вызывает уникальную ошибку при вставке
8
Во время написания запроса однажды мне пришла мысль, и она застряла в моей голове.
Что предпочтительнее: сначала проверить, существует ли значение для уникального столбца, а затем вставить или вставить и позволить db вызвать уникальную ошибку ограничения? Будет ли это вообще иметь значение?
Изменить: как предлагается ниже в ответе, что эта проблема зависит от базы данных, я добавляю тег postgresql.
Я не думаю, что ваш вопрос действительно независим от базы данных. Правильный ответ может зависеть от деталей реализации, которые могут варьироваться от поставщика к поставщику и изменяться в зависимости от следующей версии. Я бы проверил в параллельном режиме, прежде чем выбрать какой-либо подход в любой СУБД.
Прямо сейчас на SQL Server 2008 R2 я использую следующее:
Низкий параллелизм и небольшое количество модификаций. Чтобы сохранить одну строку, я сериализуюсь с помощью sp_getapplock и использую MERGE. Я испытываю стресс при высоком параллелизме, чтобы убедиться, что он работает
Более высокий параллелизм и / или объем. Чтобы избежать параллелизма и повышения производительности, я не сохраняю по одной строке за раз. Я накапливаю изменения на своем сервере приложений и использую TVP для сохранения пакетов. Тем не менее, чтобы избежать проблем, связанных с параллелизмом, я сериализуюсь с использованием sp_getapplock перед MERGE. Опять же, я проверяю тестирование в условиях высокого параллелизма, чтобы убедиться, что оно работает.
В результате мы имеем хорошую производительность и проблемы, связанные с отсутствием параллелизма в работе: нет тупиков, нет нарушений PK / уникальных ограничений и т. Д.
так что вы хотите сказать, что если проблемы с параллелизмом решаются хорошо, тогда проверка в первую очередь является хорошей идеей?
codecool
1
Да, обычно избегать ошибок лучше, чем генерировать и перехватывать исключения, но вам нужно сравнить их на своей платформе.
АК
7
Пусть БД выдаст ошибку.
Первое тестирование не безопасно для параллелизма, потому что в конечном итоге вы получите коллизию, потому что 2 потока могут пройти «НЕ СУЩЕСТВУЕТ», и оба будут пытаться писать. Это относится и к стратегиям READ COMMITTED, и к MVCC / Snapshot.
Вы можете использовать подсказки блокировки для принудительной изоляции, но вы снижаете производительность.
Я называю это паттерном JFDI (SO link). Для «обновления, если существует», смотрите это здесь: Нужна помощь Устранение неполадок Сценарий тупика Sql Server 2005 . Это SQL Server. MySQL имеет INSERT IGNORE, который обрабатывает это изящно. Не уверен насчет остальных
Я думаю, что полезно выполнять проверку (и грациозно проваливаться), но следовать пословице «доверяй, но проверяй», чтобы уловить ошибку. Причина? Обработка ошибок стоит дорого. Сегодня я работаю над некоторыми тестами, которые должны показать, имеет ли этот комментарий смысл. Если этот комментарий исчезнет, вы знаете результат. :-)
Аарон Бертран
Также в 2008 году, MERGEвозможно, это разрешило наблюдения Пола, но я не проверял это на высоких скоростях передачи. Главным образом потому, что мне еще предстоит тренировать свой мозг, чтобы понять этот синтаксис.
Аарон Бертран
1
Моя вина. Я сделал некоторые наблюдения в моем тестировании сегодня. Имейте в виду, что это очень изолированные тесты без параллелизма. Для прямых вставок проверка в первую очередь и устранение ошибки примерно в 10 раз быстрее, чем допущение ошибки. Но в других случаях, когда вы собираетесь выполнять более сложную обработку ошибок (TRY / CATCH или IF @@ ERROR <> 0, с ROLLBACK или THROW и т. Д.), Это примерно вдвое медленнее, если вы проверите сначала. Я еще раз подчеркну, что это всего лишь мои первоначальные наблюдения, и есть много факторов, которые могут повлиять на его влияние. Может пройти некоторое время, прежде чем я смогу подробно рассказать об этом в блоге.
Пусть БД выдаст ошибку.
Первое тестирование не безопасно для параллелизма, потому что в конечном итоге вы получите коллизию, потому что 2 потока могут пройти «НЕ СУЩЕСТВУЕТ», и оба будут пытаться писать. Это относится и к стратегиям READ COMMITTED, и к MVCC / Snapshot.
Вы можете использовать подсказки блокировки для принудительной изоляции, но вы снижаете производительность.
Я называю это паттерном JFDI (SO link). Для «обновления, если существует», смотрите это здесь: Нужна помощь Устранение неполадок Сценарий тупика Sql Server 2005 . Это SQL Server. MySQL имеет INSERT IGNORE, который обрабатывает это изящно. Не уверен насчет остальных
источник
MERGE
возможно, это разрешило наблюдения Пола, но я не проверял это на высоких скоростях передачи. Главным образом потому, что мне еще предстоит тренировать свой мозг, чтобы понять этот синтаксис.