Обновить одну таблицу MySQL значениями из другой

93

Я пытаюсь обновить одну таблицу MySQL на основе информации из другой.

Моя originalтаблица выглядит так:

id | value
------------
1  | hello
2  | fortune
3  | my
4  | old
5  | friend

А tobeupdatedтаблица выглядит так:

uniqueid | id | value
---------------------
1        |    | something
2        |    | anything
3        |    | old
4        |    | friend
5        |    | fortune

Я хочу , чтобы обновить idв tobeupdatedс idот на originalоснове value(строк , хранящихся в VARCHAR(32)поле).

Обновленная таблица, надеюсь, будет выглядеть так:

uniqueid | id | value
---------------------
1        |    | something
2        |    | anything
3        | 4  | old
4        | 5  | friend
5        | 2  | fortune

У меня есть запрос, который работает, но очень медленно:

UPDATE tobeupdated, original
SET tobeupdated.id = original.id
WHERE tobeupdated.value = original.value

Это приводит к максимальной загрузке процессора и, в конечном итоге, к тайм-ауту, когда выполняется только часть обновлений (есть несколько тысяч значений для сопоставления). Я знаю, что сопоставление по valueбудет медленным, но это единственные данные, которые мне нужно сопоставить вместе.

Есть ли лучший способ обновить такие значения? Я мог бы создать третью таблицу для объединенных результатов, если бы это было быстрее?

Я пробовал MySQL - как мне обновить таблицу значениями из другой таблицы? , но это не особо помогло. Любые идеи?

Заранее благодарим за помощь новичку в MySQL!

Суперангел
источник
2
Есть ли у столбца «значение» индекс?
noodl
Привет, лапша; нет, valueв данный момент индекса нет.
Superangel

Ответы:

211
UPDATE tobeupdated
INNER JOIN original ON (tobeupdated.value = original.value)
SET tobeupdated.id = original.id

Это должно сработать, и на самом деле это именно то, что вы делаете. Однако я предпочитаю синтаксис JOIN для объединений, а не несколько условий WHERE, я думаю, что его легче читать.

Что касается медленной работы, насколько велики таблицы? У вас должны быть индексы tobeupdated.valueиoriginal.value

EDIT: мы также можем упростить запрос

UPDATE tobeupdated
INNER JOIN original USING (value)
SET tobeupdated.id = original.id

USING- это сокращение, когда обе таблицы соединения имеют одинаковое имя, keyнапример id. т.е. равное соединение - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join

проводной00
источник
3
Спасибо, wired00! Это прекрасно работает. Таблицы довольно большие ( original100 000+ записей и tobeupdated10 000+), поэтому я принял ваш совет и noodl по поводу индексов, и теперь весь запрос завершается менее чем за секунду. Не могу поверить в разницу !? Большое спасибо за Вашу помощь; Я многому научился!
Superangel
5
Приятно слышать :) Я тоже многому научился здесь. Мне очень нравится этот сайт, так как вы можете
столкнуться
спасибо .. Я так много пробовал из stackoverflow .. это наконец сработало
Jaxx0rr
Просто хотел упомянуть, что простое UPDATE с WHERE было намного быстрее, чем синтаксис JOIN. Около 10.000 строк.
Alex2php
1
Их ключевой ингредиент, конечно, обозначается как индекс. мне потребовалось обновить 300K записей за 4 секунды, в отличие от тайм-аутов без них.
Amjo
0

Это зависит от того, как используются эти таблицы, но вы можете рассмотреть возможность включения триггера в исходную таблицу при вставке и обновлении. Когда вставка или обновление завершены, обновите вторую таблицу на основе только одного элемента из исходной таблицы. Так будет быстрее.

Firegnom
источник
Спасибо firegnom; Я никогда раньше не использовал триггеры, но обязательно прочту о них.
Superangel