Мне нужно установить значения всех полей записи с определенным ключом (на самом деле ключ является составным), вставив запись, если записи с таким ключом еще нет.
REPLACE
кажется, что он предназначен для работы, но в то же время его справочная страница предлагает
INSERT ... ON DUPLICATE KEY UPDATE
.
Что из них лучше выбрать и почему?
Единственный «побочный эффект» REPLACE
этого приходит мне на ум - это увеличивает значения автоинкремента (к счастью, я их не использую), хотя, INSERT ... ON DUPLICATE KEY UPDATE
вероятно, не будет. Какие еще практические отличия следует учитывать? В каких конкретных случаях можно REPLACE
предпочесть INSERT ... ON DUPLICATE KEY UPDATE
и наоборот?
Ответы:
REPLACE
внутренне выполняет удаление, а затем вставку. Это может вызвать проблемы, если у вас есть ограничение внешнего ключа, указывающее на эту строку. В этой ситуацииREPLACE
может произойти сбой или хуже: если ваш внешний ключ настроен на каскадное удаление, этоREPLACE
приведет к удалению строк из других таблиц. Это может произойти, даже если ограничение было выполнено как до, так и послеREPLACE
операции.Использование
INSERT ... ON DUPLICATE KEY UPDATE
позволяет избежать этой проблемы и поэтому является предпочтительным.источник
INSERT ... ON DUPLICATE KEY UPDATE
выглядит значительно «лучше», то в каких случаях «ЗАМЕНИТЬ» может быть лучшим выбором?REPLACE
Обновит значение автоматического приращения вашего PK, если оно делаетDELETE
иINSERT
. Именно этого я и хочу. Я не хочу, чтобы потребитель нашел запись под одним и тем же ПК, поэтому они не получают строк. Когда я хочу, чтобы они его нашли (актуальное обновление), я используюUPDATE
REPLACE
большеINSERT ... ON DUPLICATE KEY UPDATE
? ПочемуINSERT
+DELETE
когда-либо предпочтительнееUPDATE
?Чтобы ответить на вопрос с точки зрения производительности, я провел тест, используя оба метода
Замена в включает в себя:
1. Попытайтесь вставить в таблицу
2. Если 1 не удается, удалить строку и вставить новую строку
Вставка при дублировании ключа Обновление включает в себя:
1. Попытку вставить в таблицу
2. Если 1 не удается, обновить строку
Если все необходимые шаги выполнены вставки, разницы в производительности быть не должно. Скорость должна зависеть от количества задействованных обновлений. В худшем случае, когда все утверждения обновляются.
Я пробовал оба утверждения в моей таблице InnoDB, содержащие 62 510 записей (только обновления). На скорости набора:
Заменить на: 77,411 секунды
Вставить при дублировании ключа Обновление: 2,446 секунды
Insert on Duplicate Key update is almost 32 times faster.
Размер таблицы: 1249250 строк с 12 столбцами на Amazon m3.medium.
источник
Insert on Duplicate Key Replace
? Это было медленнее?ON DUPLICATE KEY UPDATE
, вы не можете писатьON DUPLICATE KEY REPLACE
. Если вы хотите обновить все значения существующей строки при дублировании ключа, вы должны написатьON DUPLICATE KEY UPDATE col1=VALUES(col1), col2=VALUES(col2), ...
- вам нужно перечислить все столбцы вручную.При использовании
REPLACE
вместоINSERT ... ON DUPLICATE KEY UPDATE
я иногда наблюдаю проблемы с блокировкой ключей или взаимоблокировкой, когда для данного ключа быстро поступает несколько запросов. Атомарность последнего (помимо того, что оно не вызывает каскадных удалений) - еще одна причина для его использования.источник
Если вы не перечислите все столбцы, я думаю,
REPLACE
что все неупомянутые столбцы сбросят их значения по умолчанию в замененных строках.ON DUPLICATE KEY UPDATE
оставит неупомянутые столбцы без изменений.источник
Я только что на собственном опыте выяснил, что в случае таблиц с системой хранения FEDERATED
INSERT...ON DUPLICATE KEY UPDATE
операторы принимаются, но терпят неудачу (с ошибкой 1022: не могу записать; дублирующий ключ в таблице ...), если дублирующийся ключ происходит нарушение - см. соответствующий маркер на этой странице Справочного руководства MySQL.К счастью, я смог использовать его
REPLACE
вместоINSERT...ON DUPLICATE KEY UPDATE
своего триггера после вставки для достижения желаемого результата репликации изменений в FEDERATED-таблицу.источник
Replace кажется, что он выполняет две операции в случае, если ключ уже существует. Возможно, это означает, что между ними есть разница в скорости?
(INSERT) одно обновление против одного удаления + одна вставка (REPLACE)
РЕДАКТИРОВАТЬ: Мое предположение, что замена может быть медленнее, на самом деле совершенно неверно. Ну, в любом случае, согласно этому сообщению в блоге ... http://www.tokutek.com/2010/07/why-insert-on-duplicate-key-update-may-be-slow-by-incurring-disk-seeks /
источник
«Возможно, что в случае ошибки дублирования ключа, механизм хранения может выполнить REPLACE как обновление, а не удаление плюс вставку, но семантика останется той же».
http://dev.mysql.com/doc/refman/5.7/en/replace.html
источник
REPLACE иногда кажется необходимым, потому что INSERT IGNORE не работает с преобразованиями данных.
Если я сделаю это, я установлю только самый большойCityPop для себя:
Если я это сделаю, я неправильно использую функцию GROUP:
И если я это сделаю, MySQL не распознает имя столбца:
Это работает, но кажется просто уродливым:
источник
INSERT IGNORE
запрос завершится успешно (и выдаст предупреждение), если внешнее ограничение не сработает ! Если вы хотите поймать такую ошибку, лучше используйтеON DUPLICATE KEY UPDATE
безIGNORE
.