Zaktualizuj jedną tabelę MySQL wartościami z innej

94

Próbuję zaktualizować jedną tabelę MySQL na podstawie informacji z innej.

Mój originalstół wygląda następująco:

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

A tobeupdatedtabela wygląda tak:

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

Chcę zaktualizować idw tobeupdatedz idze originalna podstawie value(ciągi przechowywane w VARCHAR(32)polu).

Mam nadzieję, że zaktualizowana tabela będzie wyglądać następująco:

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

Mam zapytanie, które działa, ale jest bardzo wolne:

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

To maksymalizuje mój procesor i ostatecznie prowadzi do przekroczenia limitu czasu z tylko ułamkiem wykonanych aktualizacji (jest kilka tysięcy wartości do dopasowania). Wiem, że dopasowywanie według valuebędzie wolne, ale to jedyne dane, które muszę dopasować.

Czy istnieje lepszy sposób aktualizowania takich wartości? Mógłbym utworzyć trzecią tabelę dla połączonych wyników, gdyby to było szybsze?

Próbowałem MySQL - Jak mogę zaktualizować tabelę wartościami z innej tabeli? , ale to nie pomogło. Jakieś pomysły?

Z góry dziękujemy za pomoc nowicjuszowi MySQL!

Superanioł
źródło
2
Czy Twoja kolumna „wartość” ma indeks?
noodl
Cześć makaron; nie, valuew tej chwili nie ma indeksu.
Superangel

Odpowiedzi:

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

To powinno wystarczyć i naprawdę robi dokładnie to, co twoje. Jednak wolę składnię „JOIN” dla złączeń zamiast wielu warunków „WHERE”, myślę, że jest łatwiejsza do odczytania

Jeśli chodzi o wolne działanie, jak duże są stoły? Powinieneś mieć indeksy na tobeupdated.valueioriginal.value

EDYCJA: możemy również uprościć zapytanie

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

USINGjest skrótem, gdy obie tabele sprzężenia mają identyczną nazwę, na keyprzykład id. tj. dołączenie equi - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join

przewodowy00
źródło
3
Dzięki wired00! To działa doskonale. Tabele są dość duże ( ponad original100 000 wpisów i tobeupdatedponad 10 000), więc posłuchałem rady Twojej i firmy Noodl dotyczącej indeksów i teraz całe zapytanie kończy się w niecałą sekundę. Nie mogę uwierzyć w różnicę !? Dziękuję bardzo za Twoją pomoc; Wiele się nauczyłem!
Superangel
5
Miło to słyszeć :) Tutaj też wiele się uczę. Naprawdę podoba mi się ta strona, ponieważ możesz być narażona na wiele różnych problemów i pomysłów
wired00,
dziękuję .. próbowałem tylu rzeczy ze stackoverflow .. ten w końcu zadziałał
Jaxx0rr
Chciałem tylko wspomnieć, że prosta AKTUALIZACJA z GDZIE była znacznie szybsza niż składnia JOIN. Około 10.000 rzędów.
Alex2php
1
Ich kluczowym składnikiem jest oczywiście przypisanie jako indeksu. zajęło mi zaktualizowanie 300 000 rekordów w 4 sekundy, w przeciwieństwie do limitów czasu bez nich.
Amjo
0

Zależy to od przeznaczenia tych tabel, ale możesz rozważyć umieszczenie wyzwalacza na oryginalnej tabeli podczas wstawiania i aktualizowania. Po zakończeniu wstawiania lub aktualizacji zaktualizuj drugą tabelę na podstawie tylko jednego elementu z oryginalnej tabeli. Będzie szybciej.

firegnom
źródło
Dzięki, firegnom; Nigdy wcześniej nie używałem wyzwalaczy, ale na pewno o nich poczytam.
Superangel