2011-04-20 31 views
80

Estoy tratando de actualizar una tabla MySQL basada en información de otra.Actualizar una tabla MySQL con valores de otra

Mi mesa original parece:

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

Y la mesa tobeupdated parece:

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

Quiero actualizar id en tobeupdated con el id de original basado en value (cadenas almacenadas en VARCHAR(32) campo).

La tabla actualizada de esperar que el siguiente aspecto:

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

Tengo una consulta que funciona, pero es muy lento:

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

Este maxes mi CPU y finalmente lleva a un tiempo de espera con solo una fracción de las actualizaciones realizadas (hay varios miles de valores para que coincidan). Sé que la coincidencia por value será lenta, pero este es el único dato que tengo para unirlos.

¿Existe alguna forma mejor de actualizar valores como este? Podría crear una tercera tabla para los resultados combinados, si eso fuera más rápido?

Intenté MySQL - How can I update a table with values from another table?, pero en realidad no me ayudó. ¿Algunas ideas?

¡Gracias de antemano por ayudar a un principiante de MySQL!

+2

¿Su columna de 'valor' tiene un índice? – noodl

+0

Hola noodl; no, 'value' no tiene un índice en este momento. – Superangel

Respuesta

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

Eso debería hacerlo, y realmente está haciendo exactamente lo que usted es. Sin embargo, prefiero la sintaxis 'JOIN' para las uniones en lugar de varias condiciones 'WHERE', creo que es más fácil de leer

En cuanto a la lentitud, ¿qué tan grandes son las tablas? Debe tener índices en tobeupdated.value y original.value

EDIT: también podemos simplificar la consulta

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

USING es la abreviatura cuando las dos tablas de una unión tienen una idéntica llamado key como id. es decir, un equi-join - http://en.wikipedia.org/wiki/Join_(SQL)#Equi-join

+3

Gracias wired00! Esto funciona perfectamente Las tablas son bastante grandes ('original' es de más de 100.000 entradas y' tobeupdated' 10.000+), así que tomé su consejo y el de noodl sobre los índices y la consulta completa ahora termina en menos de un segundo. ¡No puedo creer la diferencia !? Muchas gracias por su ayuda; ¡He aprendido mucho! – Superangel

+5

Eso es genial de escuchar :) Aprendo mucho aquí también. Me gusta mucho este sitio ya que puede estar expuesto a muchos problemas e ideas diferentes – wired00

+0

gracias .. Probé muchas cosas de stackoverflow ... esta finalmente funcionó –

0

Depende del uso de esas tablas, pero puede considerar colocar el activador en la tabla original al insertar y actualizar. Cuando finalice la inserción o actualización, actualice la segunda tabla basándose en un solo elemento de la tabla original. Será más rápido.

+0

Gracias firegnom; Nunca antes había usado disparadores, pero me aseguraré de leerlos. – Superangel

Cuestiones relacionadas