2012-06-25 21 views
15

¿Hay un más-eficiente, de manera menos laboriosa de copiar todos los registros de una tabla a otra que hacer esto:MySQL copia de manera eficiente todos los registros de una tabla a otra

INSERT INTO product_backup SELECT * FROM product 

Por lo general, la tabla product llevará a cabo alrededor de 50,000 registros. Ambas tablas son idénticas en estructura y tienen 31 columnas en ellas. Me gustaría señalar que esto es no mi diseño de base de datos, he heredado un sistema heredado.

+5

que piensa que esto es la mejor manera. De esta manera, también conserva índices. –

+1

Speedwise es lo mejor posible. Por supuesto, puede aplazar la creación de índices en la tabla de copias de seguridad hasta que todos los datos se hayan copiado, lo que aumentará significativamente la velocidad de inserción. – fvu

+0

Eso es interesante, gracias. Era inquisitivo respecto a la copia de datos y me preguntaba si esto era una pérdida en la base de datos (el 'SELECT *' me delató, o si me llevaría mucho tiempo procesarlo debido a la forma en que se construye la consulta). Si esta es una forma aceptable de copiar los datos, entonces está bien. – crmpicco

Respuesta

9

Creo que esta es la mejor manera de copiar registros de una tabla a otra. De esta manera, también conservará los índices existentes de la tabla de destino.

1

No creo que esto sea válido para una tabla de 50k pero: Si tiene el volcado de la base de datos, puede volver a cargar una tabla desde él. A medida que desea cargar una tabla en otra podría cambiar el nombre de la tabla en el vertedero con un comando sed: Aquí tienes algunos consejos: http://blog.tsheets.com/2008/tips-tricks/mysql-restoring-a-single-table-from-a-huge-mysqldump-file.html

Una alternativa (dependiendo de su diseño) sería el uso de disparadores en las inserciones de la tabla original para que la tabla duplicada también obtenga los datos.

Y una mejor alternativa sería crear otra instancia de MySQL y ejecutarla en una configuración de maestro-esclavo o en un modo de volcado diario maestro/cargar esclavos.

4
mysqldump -R --add-drop-table db_name table_name > filepath/file_name.sql 

Esto tomará un volcado de tablas especificadas con una opción de soltar para eliminar la tabla existente cuando la importe. entonces hazlo,

mysql db_name < filepath/file_name.sql 
+0

Debería haber agregado que estoy haciendo esto en código PHP. Se realizará antes de que se lleven a cabo una serie de INSERTES y ACTUALIZACIONES en la tabla 'producto', por lo que estaría buscando hacerlo en código PHP en lugar de las funciones de administración de MySQL. – crmpicco

12

Solo falta una cosa. Sobre todo, si usted está utilizando InnoDB, es que desea agregar explícitamente una cláusula ORDER BY en la instrucción SELECT para asegurarse de que está insertando filas en la clave principal (índice agrupado) orden:

INSERT INTO product_backup SELECT * FROM product ORDER BY product_id 

considerar la eliminación de índices secundarios en la tabla de respaldo si no son necesarios. Esto también ahorrará algo de carga en el servidor.

Por último, si usted está usando InnoDB, reducir el número de bloqueos de registro que se requieren y solo se bloquean de forma explícita ambas tablas:

LOCK TABLES product_backup WRITE; 
LOCK TABLES product_id READ; 
INSERT INTO product_backup SELECT * FROM product ORDER BY product_id; 
UNLOCK TABLES; 

El material de bloqueo probablemente no va a hacer una gran diferencia, ya que el bloqueo de filas es muy rápido (aunque no tan rápido como los bloqueos de mesa), pero desde que lo preguntaste.

+0

Estoy usando el motor MyISAM. Mencioné en una publicación anterior que he heredado un sistema heredado, por lo que es MyISAM por el momento. – crmpicco

+0

no se pudo ordenar que crear un árbol de índice que está desequilibrado? ¿En qué caso el orden aleatorio puede ser mejor para la clave primaria? –

+0

@DannyStaple, el árbol es plano cuando se inserta en un índice en orden ordenado con MyISAM. Esto mejora el rendimiento (no tener que reconstruir el índice), y ahorra espacio. De [documentación de MySQL] (http://dev.mysql.com/doc/refman/5.0/en/myisam-storage-engine.html): "Cuando las filas se insertan en orden ordenado (como cuando se utiliza una columna AUTO_INCREMENT), el árbol de índice se divide para que el nodo alto solo contenga una clave. Esto mejora la utilización del espacio en el árbol de índice ". –

1

DROP la tabla de destino:

DROP TABLE DESTINATION_TABLE; 
CREATE TABLE DESTINATION_TABLE AS (SELECT * FROM SOURCE_TABLE); 
+0

¿Qué sucede si ya hay datos en la tabla de destino que OP desea conservar y agregar? – Martin

+0

por qué soltar y crear tabla en lugar de ELIMINAR FROM tabla_destino; INSERTAR EN la tabla de destino SELECCIONAR * ¿DESDE el producto? ¿Cuál es más eficiente? –

Cuestiones relacionadas