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.