Плюсы и минусы проверки, существует ли значение для уникального столбца или пусть db вызывает уникальную ошибку при вставке


8

Во время написания запроса однажды мне пришла мысль, и она застряла в моей голове.

Что предпочтительнее: сначала проверить, существует ли значение для уникального столбца, а затем вставить или вставить и позволить db вызвать уникальную ошибку ограничения? Будет ли это вообще иметь значение?

Изменить: как предлагается ниже в ответе, что эта проблема зависит от базы данных, я добавляю тег postgresql.

Ответы:


3

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

Прямо сейчас на SQL Server 2008 R2 я использую следующее:

  1. Низкий параллелизм и небольшое количество модификаций. Чтобы сохранить одну строку, я сериализуюсь с помощью sp_getapplock и использую MERGE. Я испытываю стресс при высоком параллелизме, чтобы убедиться, что он работает

  2. Более высокий параллелизм и / или объем. Чтобы избежать параллелизма и повышения производительности, я не сохраняю по одной строке за раз. Я накапливаю изменения на своем сервере приложений и использую TVP для сохранения пакетов. Тем не менее, чтобы избежать проблем, связанных с параллелизмом, я сериализуюсь с использованием sp_getapplock перед MERGE. Опять же, я проверяю тестирование в условиях высокого параллелизма, чтобы убедиться, что оно работает.

В результате мы имеем хорошую производительность и проблемы, связанные с отсутствием параллелизма в работе: нет тупиков, нет нарушений PK / уникальных ограничений и т. Д.


так что вы хотите сказать, что если проблемы с параллелизмом решаются хорошо, тогда проверка в первую очередь является хорошей идеей?
codecool

1
Да, обычно избегать ошибок лучше, чем генерировать и перехватывать исключения, но вам нужно сравнить их на своей платформе.
АК

7

Пусть БД выдаст ошибку.

Первое тестирование не безопасно для параллелизма, потому что в конечном итоге вы получите коллизию, потому что 2 потока могут пройти «НЕ СУЩЕСТВУЕТ», и оба будут пытаться писать. Это относится и к стратегиям READ COMMITTED, и к MVCC / Snapshot.

Вы можете использовать подсказки блокировки для принудительной изоляции, но вы снижаете производительность.

Я называю это паттерном JFDI (SO link). Для «обновления, если существует», смотрите это здесь: Нужна помощь Устранение неполадок Сценарий тупика Sql Server 2005 . Это SQL Server. MySQL имеет INSERT IGNORE, который обрабатывает это изящно. Не уверен насчет остальных


ОКК. Я не думал об этом! В случае параллелизма даже проверка может закончиться неудачей. :)
codecool


Я думаю, что полезно выполнять проверку (и грациозно проваливаться), но следовать пословице «доверяй, но проверяй», чтобы уловить ошибку. Причина? Обработка ошибок стоит дорого. Сегодня я работаю над некоторыми тестами, которые должны показать, имеет ли этот комментарий смысл. Если этот комментарий исчезнет, ​​вы знаете результат. :-)
Аарон Бертран

Также в 2008 году, MERGEвозможно, это разрешило наблюдения Пола, но я не проверял это на высоких скоростях передачи. Главным образом потому, что мне еще предстоит тренировать свой мозг, чтобы понять этот синтаксис.
Аарон Бертран

1
Моя вина. Я сделал некоторые наблюдения в моем тестировании сегодня. Имейте в виду, что это очень изолированные тесты без параллелизма. Для прямых вставок проверка в первую очередь и устранение ошибки примерно в 10 раз быстрее, чем допущение ошибки. Но в других случаях, когда вы собираетесь выполнять более сложную обработку ошибок (TRY / CATCH или IF @@ ERROR <> 0, с ROLLBACK или THROW и т. Д.), Это примерно вдвое медленнее, если вы проверите сначала. Я еще раз подчеркну, что это всего лишь мои первоначальные наблюдения, и есть много факторов, которые могут повлиять на его влияние. Может пройти некоторое время, прежде чем я смогу подробно рассказать об этом в блоге.
Аарон Бертран
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.