2015-03-14 8 views
1

Я немного нуб, когда речь заходит о sql-запросах, и я только реально работал с базовыми операторами SELECT, UPDATE, DELETE. Теперь мне нужно обновить много строк (50+) в вертикальной таблице, и им работает заявление, как это:Есть ли более эффективный способ запуска нескольких операторов SQL UPDATE

UPDATE `postmeta` SET meta_value = 'John' WHERE `meta_key` = 'name' AND `post_id` = 29230; 
UPDATE `postmeta` SET meta_value = 'Johnson' WHERE `meta_key` = 'last_name' AND `post_id` = 29230; 
UPDATE `postmeta` SET meta_value = 'www.johnsonsdiner.com' WHERE `meta_key` = 'url' AND `post_id` = 29230; 
UPDATE `postmeta` SET meta_value = '[email protected]' WHERE `meta_key` = 'mail' AND `post_id` = 29230; 
UPDATE `postmeta` SET meta_value = '12341234' WHERE `meta_key` = 'phone' AND `post_id` = 29230; 
... + 45 more 

Обратите внимание, что post_id является тем же самым, в то время как meta_key отличается.

Есть ли лучший способ запускать все эти обновления, которые будут иметь лучшую производительность для mySQL? имеет ли значение добавить LIMIT 1 в каждое утверждение?

Любая помощь приветствуется

+0

Моим советом было бы вернуться к правильной нормированной схеме 3NF, тогда вы могли бы сделать всю партию в операторе _one_ update. Эта конкретная схема выглядит так, как те, которые объединены этими ORM, которые дают вам гибкость обновлений псевдосхемы без изменения схемы _actual_ DB за счет более сложных запросов. В 3NF будет таблица с _one_ row для каждого идентификатора сообщения, и она будет содержать имя, last_name и т. Д. В качестве столбцов. – paxdiablo

+0

@paxdiablo - Я знаю. Мне бы это понравилось, если бы я мог изменить схему, но, к сожалению, это не вариант. поэтому я должен найти способ обойти это, не нажимая слишком высокую производительность. –

ответ

3

вы можете использовать только один update с case заявление на доли не имеет общих условий также привести общие условия в которых положение:

UPDATE `postmeta` 
     SET meta_value = case 
      when `meta_key` = 'name' then 'John' 
      when `meta_key` = 'last_name' then 'Johnson' 
      when `meta_key` = 'url' then 'www.johnsonsdiner.com' 
      when `meta_key` = 'mail' then '[email protected]' 
      when `meta_key` = 'phone' then '12341234' 
      . 
      ...45 more 
      . 
      end 
where `post_id` = 29230; 
+0

Это улучшит производительность по сравнению с отдельными операциями обновления? Im волновался, что ему придется запускать все случаи против всех meta_keys, чтобы знать, нужно ли его устанавливать? любой способ проверить разницу в производительности? –

+0

, конечно, проверка post_id одно время имеет лучшую производительность, чем много раз, также для каждой команды обновления db-движок проверяет все строки для проверки состояния (45 * numberofrows), но в одном обновлении с аргументами case он проверяет (numberofrows * (меньше, чем 45)) раз, потому что условие возможно вначале, когда в заявлении дела – jfun

+0

Мне было любопытно и попробовал. Ни один из «meta_key» не был обновлен. Что не так в этой скрипте: http://sqlfiddle.com/#!9/3c6ad/1 – Trinimon

0

Еще один подход заключается в использовании INSERT ON DUPLICATE KEY UPDATE, если вы знаете первичный ключ для каждой обновляемой строки.

Так если предположить (для целей иллюстрации), что (post_id, meta_key) ваш первичный ключ, следующий запрос будет решить вашу потребность:

INSERT INTO postmeta (post_id, meta_key, meta_value) 
VALUES (29230,'name','John'), (29230,'last_name','Johnson'),... 
ON DUPLICATE KEY UPDATE meta_value = VALUES(meta_value) 

Если (post_id, meta_key) не объявлен как ограничение уникальности, то вы должны были бы первым сделайте выбор, чтобы знать первичный ключ для строк, которые вы обновляете, но будьте осторожны и учитывайте возможные условия гонки, которые могут применяться в вашей ситуации.

+2

«вставить в дублирующее обновление» хорошо, когда у нас есть вставки, и мы хотим обновить некоторые значения, если существуют определенные значения. здесь в этом сценарии мы вообще не вставляем, поэтому даже пакетные обновления (как это было в вопросе) намного лучше, чем INSERT ON DUPLICATE KEY UPDATE – jfun

+0

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

Смежные вопросы