В MySQL быстрее удалить, а затем вставить или быстрее обновить существующие строки? - PullRequest
9 голосов
/ 26 октября 2010

Прежде всего, позвольте мне сказать, что я использую PHP-фреймворк Yii, поэтому я хотел бы остаться в пределах его определенного набора операторов SQL, если это возможно. Я знаю, что мог бы, вероятно, создать один огромный длинный SQL-оператор, который бы делал все, но я бы предпочел не идти туда.

ОК, представьте, что у меня есть таблица Users и таблица FavColors. Затем у меня есть форма, в которой пользователи могут выбирать свои цветовые предпочтения, установив один или несколько флажков в большом списке возможных цветов.

Эти результаты хранятся в виде нескольких строк в таблице FavColors следующим образом (id, user_id, color_id).

Теперь представьте, что пользователь заходит и меняет свои цветовые предпочтения. В этом сценарии, какой будет наиболее эффективный способ получить новые цветовые предпочтения в базе данных?

Вариант 1:

  • Массовое удаление всех строк, в которых указан user_id
  • Затем выполните массовую вставку всех новых строк

Вариант 2:

  • Просмотрите каждую текущую строку, чтобы увидеть, что изменилось, и обновите соответственно
  • Если нужно вставить больше строк, сделайте это.
  • Если необходимо удалить строки, сделайте это.

Мне нравится первый вариант, потому что он требует только двух операторов, но что-то не так, когда вы удаляете строку, чтобы потенциально вернуть почти те же самые данные. Существует также проблема автоматического увеличения идентификаторов до более высоких значений. быстро, и я не знаю, следует ли этого избегать, когда это возможно.

Вариант 2 потребует гораздо больше работы по программированию, но предотвратит ситуации, когда я удаляю строку, просто чтобы создать ее снова. Однако добавление дополнительной нагрузки в PHP может не стоить уменьшения нагрузки для MySQL.

Есть мысли? Что бы вы все сделали?

Ответы [ 2 ]

9 голосов
/ 26 октября 2010

UPDATE намного быстрее. Когда вы UPDATE, записи таблицы просто перезаписываются новыми данными. И все это нужно сделать снова на INSERT.

Когда вы DELETE, индексы должны быть обновлены (помните, что вы удаляете всю строку, а не только столбцы, которые нужно изменить), и блоки данных могут перемещаться (если вы достигнете предела PCTFREE). Также удаляем и добавляем новые идентификаторы записей об изменениях в auto_increment, так что если эти записи имеют отношения, которые будут нарушены или потребуются также обновления. Я бы пошел на UPDATE.

Вот почему вы должны предпочесть INSERT ... ON DUPLICATE KEY UPDATE вместо REPLACE.

Первая операция UPDATE в случае нарушения ключа, вторая - DELETE / INSERT

ОБНОВЛЕНИЕ: Вот пример INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;

Подробнее читайте в обновлении Документация

1 голос
/ 26 октября 2010

Филипп, Вы пытались делать готовые заявления? С подготовленными утверждениями вы можете пакетировать один запрос с различными параметрами и вызывать его несколько раз. В конце цикла вы можете выполнить их все с минимальной задержкой в ​​сети. Я использовал подготовленные заявления с php, и это прекрасно работает. Немного более запутанно, чем заявления, подготовленные Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...