Actualizar una tabla MySQL con valores de otra


93

Estoy intentando actualizar una tabla MySQL en función de la información de otra.

Mi originalmesa se parece a:

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

Y la tobeupdatedmesa se ve así:

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

Quiero actualizar iden tobeupdatedel idde originalbase en value(cadenas almacenadas en el VARCHAR(32)campo).

Con suerte, la tabla actualizada se verá así:

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

Tengo una consulta que funciona, pero es muy lenta:

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

Esto maximiza mi CPU y eventualmente conduce a un tiempo de espera con solo una fracción de las actualizaciones realizadas (hay varios miles de valores para coincidir). Sé que la comparación valueserá lenta, pero estos son los únicos datos que tengo para combinarlos.

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

Probé MySQL - ¿Cómo puedo actualizar una tabla con valores de otra tabla? , pero realmente no ayudó. ¿Algunas ideas?

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


2
¿Su columna 'valor' tiene un índice?
Noodl

Hola noodl; no, valueno tiene un índice en este momento.
Superangel

Respuestas:


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

Eso debería bastar, y realmente está haciendo exactamente lo que es el tuyo. Sin embargo, prefiero la sintaxis 'JOIN' para combinaciones en lugar de múltiples condiciones 'DONDE', creo que es más fácil de leer

En cuanto a correr lento, ¿qué tamaño tienen las mesas? Deberías tener índices en tobeupdated.valueyoriginal.value

EDITAR: también podemos simplificar la consulta

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

USINGes una abreviatura cuando ambas tablas de una combinación tienen un nombre idéntico 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 ( originalson más de 100,000 entradas y tobeupdatedmás de 10,000 ), así que seguí tu 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
Es genial escucharlo :) También aprendo mucho aquí. Me gusta mucho este sitio, usted puede estar expuesto a muchas cuestiones e ideas diferentes
wired00

gracias ... probé tantas cosas de stackoverflow ... esta finalmente funcionó
Jaxx0rr

Solo quería mencionar que una simple ACTUALIZACIÓN con WHERE era mucho más rápida que la sintaxis JOIN. Aproximadamente 10.000 filas.
Alex2php

1
El ingrediente clave es, por supuesto, la asignación como índice. me llevó actualizar 300K registros en 4 segundos en lugar de los tiempos de espera sin ellos.
Amjo

0

Depende del uso de esas tablas, pero podría considerar poner el disparador 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.


Gracias firegnom; Nunca antes había usado desencadenantes, pero me aseguraré de leer sobre ellos.
Superangel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.