Aggiorna una tabella MySQL con i valori di un'altra


93

Sto cercando di aggiornare una tabella MySQL in base alle informazioni di un'altra.

Il mio originaltavolo si presenta come:

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

E il tobeupdatedtavolo ha questo aspetto:

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

Voglio aggiornare idin tobeupdatedla idda originalin base a value(stringhe memorizzate nel VARCHAR(32)campo).

Si spera che la tabella aggiornata avrà il seguente aspetto:

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

Ho una query che funziona, ma è molto lenta:

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

Questo massimizza la mia CPU e alla fine porta a un timeout con solo una frazione degli aggiornamenti eseguiti (ci sono diverse migliaia di valori da abbinare). So che la corrispondenza per valuesarà lenta, ma questo è l'unico dato che ho per abbinarli insieme.

C'è un modo migliore per aggiornare valori come questo? Potrei creare una terza tabella per i risultati uniti, se fosse più veloce?

Ho provato MySQL - Come posso aggiornare una tabella con i valori di un'altra tabella? , ma non è stato d'aiuto. Qualche idea?

Grazie in anticipo per aiutare un principiante di MySQL!


2
La tua colonna "valore" ha un indice?
noodl

Ciao noodl; no, valuenon ha un indice al momento.
Superangel

Risposte:


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

Dovrebbe farlo, e in realtà sta facendo esattamente quello che è il tuo. Tuttavia, preferisco la sintassi "JOIN" per i join piuttosto che più condizioni "WHERE", penso sia più facile da leggere

Per quanto riguarda la lentezza, quanto sono grandi i tavoli? Dovresti avere indici su tobeupdated.valueeoriginal.value

EDIT: possiamo anche semplificare la query

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

USINGè una scorciatoia quando entrambe le tabelle di un join hanno un nome identico keycome id. cioè un equi-join - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join


3
Grazie wired00! Funziona perfettamente. Le tabelle sono piuttosto grandi ( originalsono 100.000+ voci e tobeupdated10.000+), quindi ho seguito il consiglio tuo e di noodl sugli indici e l'intera query ora termina in meno di un secondo. Non riesco a credere alla differenza !? Grazie mille per il vostro aiuto; Ho imparato molto!
Superangel

5
È fantastico sentire :) Anche qui ho imparato molto. Mi piace molto questo sito perché puoi essere esposto a molti problemi e idee diverse
cablato il

grazie .. ho provato così tante cose da stackoverflow .. questo finalmente ha funzionato
Jaxx0rr

Volevo solo menzionare che un semplice UPDATE con WHERE era molto più veloce della sintassi JOIN. Circa 10.000 righe.
Alex2php

1
Il loro ingrediente chiave è ovviamente l'assegnazione come indice. mi ha portato ad aggiornare 300.000 record in 4 secondi anziché i timeout senza di essi.
Amjo

0

Dipende dall'uso di queste tabelle, ma potresti considerare di mettere il trigger sulla tabella originale durante l'inserimento e l'aggiornamento. Al termine dell'inserimento o dell'aggiornamento, aggiorna la seconda tabella in base a un solo elemento della tabella originale. Sarà più veloce.


Grazie firegnom; Non ho mai usato trigger prima, ma mi assicurerò di leggerli.
Superangel
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.