2010-01-30 14 views
50

Actualmente estoy trabajando en la creación de un entorno para probar el rendimiento de una aplicación; Estoy probando con MySQL e InnoDB para averiguar cuál nos puede servir mejor. Dentro de este entorno, prepararemos automáticamente la base de datos (carga de volcados existentes) e instrumentaremos nuestras herramientas de prueba.InnoDB tarda más de una hora en importar archivos de 600MB, MyISAM en unos minutos

Estoy preparando para probar el mismo volcado de datos con MySQL e InnoDB, pero ya no estoy logrando llevar la importación inicial a una velocidad útil para la pieza InnoDB. El vertedero inicial tomó más tiempo, pero eso no me preocupa aún:

$ for i in testdb_myisam testdb_innodb; do time mysqldump --extended-insert $i > $i.sql; done 

real 0m38.152s 
user 0m8.381s 
sys  0m2.612s 

real 1m16.665s 
user 0m6.600s 
sys  0m2.552s 

Sin embargo, los tiempos de importación eran muy diferentes:

$ for i in testdb_myisam testdb_innodb; do time mysql $i < $i.sql; done 

real 2m52.821s 
user 0m10.505s 
sys  0m1.252s 

real 87m36.586s 
user 0m10.637s 
sys  0m1.208s 

Después de una investigación que vine Changing tables from MyISAM to InnoDB make the system slow y luego se usa set global innodb_flush_log_at_trx_commit=2:

$ time mysql testdb_innodb < testdb_innodb.sql 

real 64m8.348s 
user 0m10.533s 
sys  0m1.152s 

En mi humilde opinión todavía sorprendentemente lento. También he desactivado log_bin para estas pruebas y aquí hay una lista de all mysql variables.

¿Tengo que aceptar este largo InnoDB veces o se pueden mejorar? Tengo el control total sobre este servidor MySQL, ya que es puramente para este entorno de prueba.

Puedo aplicar configuraciones especiales solo para la importación inicial y volver a cambiarlas para pruebas de aplicaciones para que coincidan mejor con los entornos de producción.

Actualización:

Teniendo en cuenta las votaciones, he confirmación automática desactivada y los diferentes controles:

$ time (echo "SET autocommit=0; SET unique_checks=0; SET foreign_key_checks=0;" \ 
; cat testdb_innodb.sql ; echo "COMMIT;") | mysql testdb_innodb;date 

real 47m59.019s 
user 0m10.665s 
sys  0m2.896s 

La velocidad mejorada, pero no tanto. ¿Mi prueba es defectuosa?

Actualización 2:

pude tener acceso a una máquina diferente eran las importaciones sólo tomó unos 8 minutos. Comparé las configuraciones y apliqué las siguientes configuraciones a la instalación de MySQL:

innodb_additional_mem_pool_size = 20971520 
innodb_buffer_pool_size = 536870912 
innodb_file_per_table 
innodb_log_buffer_size = 8388608 
join_buffer_size = 67104768 
max_allowed_packet = 5241856 
max_binlog_size = 1073741824 
max_heap_table_size = 41943040 
query_cache_limit = 10485760 
query_cache_size = 157286400 
read_buffer_size = 20967424 
sort_buffer_size = 67108856 
table_cache = 256 
thread_cache_size = 128 
thread_stack = 327680 
tmp_table_size = 41943040 

Con estas configuraciones, ahora tengo unos 25 minutos. Aún muy lejos de los pocos minutos que lleva MyISAM, pero se está volviendo más útil para mí.

+0

¿Sabes qué? Realmente deberíamos haber movido esto a serverfault. Votado para hacer eso. Buena suerte. –

+0

@ T.J. Suena razonable. ¿Hay algo de mi parte que pueda/deba hacer? – mark

Respuesta

111

¿Probaste los granel datos Cargando Consejos del InnoDB Performance Tuning Tips (especialmente el primero):

  • Al importar datos en InnoDB, asegúrese de que MySQL no tiene confirmación automática modo habilitado porque requiere un registro de vaciado en disco para cada inserción . Para desactivar la ejecución automática durante su operación de importación, lo rodean con SET autocommit y COMMIT declaraciones:

    SET autocommit=0; 
    ... SQL import statements ... 
    COMMIT; 
    

    Si se utiliza la opción mysqldump --opt, a obtener los archivos de volcado que son rápida para importar en una tabla InnoDB, incluso sin envolverlos con las declaraciones SET autocommit y COMMIT .

  • Si tiene UNIQUE limitaciones de claves secundarias, se puede acelerar la tabla importaciones desactivando temporalmente los verificación de unicidad durante la sesión de importación :

    SET unique_checks=0; 
    ... SQL import statements ... 
    SET unique_checks=1; 
    

    Para tablas grandes, esto ahorra mucho de E/S de disco porque InnoDB puede usar su buffer de inserción para escribir registros de índice secundarios en un lote. Asegúrese de que los datos no contienen claves duplicadas .

  • Si tiene FOREIGN KEY limitaciones en las tablas, se puede velocidad hasta la mesa importaciones girando el verificación de claves foráneas para el duración de la sesión de importación:

    SET foreign_key_checks=0; 
    ... SQL import statements ... 
    SET foreign_key_checks=1; 
    

    Para tablas grandes, esto puede ahorrar una gran cantidad de E/S de disco.

OMI, todo el capítulo es vale la pena leer.

+2

Massive +1. Respuesta perfecta. –

+1

¡Gracias por ese puntero! He revisado el capítulo, ya citó las partes más relevantes de todos modos, y las apliqué y ellas volvieron a realizar la prueba. Más rápido, pero aún más lento. No puedo creer eso. Parece que estoy cometiendo un verdadero error de principiante aquí. – mark

+0

@mfn De nada. Pero, de hecho, sin confirmación automática, sin controles de exclusividad, sin controles de clave externa, debería obtener una velocidad similar. ¿Tienes algún índice en esa mesa? Tal vez soltarlos y recrearlos después de la importación masiva. –

5

¿Ha intentado iniciar una transacción desde el principio y comprometerla al final? Del question you linked: "Modifique el paso Insertar datos para iniciar una transacción al inicio y para confirmarla al final. Obtendrá una mejora, lo garantizo".

Recuerde que InnoDB es transaccional, MyISAM no lo es. Los motores transaccionales tratan cada extracto como una transacción individual si no se controla explícitamente la transacción. Esto puede ser costoso

+0

+1 también porque ha señalado lo correcto –

+0

He actualizado la pregunta con confirmación automática desactivada explícitamente. Funcionó más rápido, pero aún lleva demasiado tiempo (en mi humilde opinión). – mark

1

Tuve problemas para importar a granel y recomendar la respuesta aceptada. He encontrado también puede acelerar las cosas de manera significativa por:

  1. Dejar caer todos los índices (que no sean clave primaria), cargar los datos a continuación, volver a agregar índices
  2. Comprobar su innodb_log_file_size * innodb_log_files_in_group es suficiente para evitar la escritura en el disco en frecuencia por debajo del segundo

En cuanto al n. ° 2, los valores predeterminados de 5M * 2 no serán suficientes en un sistema moderno.Para más detalles, vea innodb_log_file_size y innodb_log_files_in_group

1

Encontré que el disco duro es el cuello de botella: los discos pasados ​​de moda son inútiles, SSD está bien, pero todavía está lejos de ser perfecto. Importar a tmpfs y copiar los datos es mucho más rápido, detalles: https://dba.stackexchange.com/a/89367/56667

Cuestiones relacionadas