2011-04-20 6 views
80

Я пытаюсь обновить одну таблицу MySQL на основе информации от другой.Обновить одну таблицу 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 - How can I update a table with values from another table?, но это действительно не помогло. Есть идеи?

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

+2

В столбце «значение» есть индекс? – noodl

+0

Hi noodl; no, 'value' на данный момент не имеет индекса. – Superangel

ответ

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

Это должно сделать это, и действительно это делает то, что у вас есть. Тем не менее, я предпочитаю синтаксис «JOIN» для объединений, а не для нескольких условий «ГДЕ», я думаю, что его легче читать

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

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

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

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

+3

Спасибо wired00! Это прекрасно работает. Таблицы довольно велики («оригинал» - 100 000+ записей и 'tobeupdated' 10 000+), поэтому я взял ваш и noodl советы об индексах, и весь запрос теперь заканчивается через секунду. Я не могу поверить в разницу !? Большое спасибо за Вашу помощь; Я многому научился! – Superangel

+5

Это здорово слышать :) Я тоже многому учусь здесь. Мне очень нравится этот сайт, так как вы можете столкнуться с множеством различных проблем и идей. – wired00

+0

спасибо. Я пробовал так много вещей из stackoverflow .. этот, наконец, работал –

0

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

+0

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

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