InnoDB inserción más rápido

8

Soy un estudiante de posgrado que investiga OLAP con Mondrian OLAP. Entonces quiero insertar datos en InnoDB (MySQL 5.5) más rápido en la carga inicial. En este entorno, el único usuario soy yo, por lo que creo que puede permitir configuraciones más flexibles para la velocidad de inserción. Por el momento, estoy usando las siguientes técnicas.

  • inhabilitar log_bin
  • habilitar skip-innodb-doublewrite
  • establecido transaction_isolationen READ-COMMITTEDo READ-UNCOMMITTED(en realidad READ-COMMITED)
  • establecido innodb_flush_log_at_trx_commiten 0o 2(en realidad 0)
  • configurado innodb_buffer_pool_sizea 5 GB (el sistema tiene 6 GB de RAM)

¿Hay más técnicas para una inserción más rápida en InnoDB? ¿Y tengo que modificar innodb_io_read_thready innodb_io_write_thread? Si necesita más información, por favor dígame.

inohiro
fuente

Respuestas:

9

SUGERENCIA # 1

Si su máquina tiene múltiples núcleos, debe aumentar lo siguiente:

[mysqld]
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000

¿Que son estos?

  • innodb_read_io_threads - El número de hilos de E / S para operaciones de lectura en InnoDB.
  • innodb_write_io_threads - El número de hilos de E / S para operaciones de escritura en InnoDB.
  • innodb_io_capacity : un límite superior de la actividad de E / S realizada por las tareas en segundo plano de InnoDB, como el vaciado de páginas del grupo de búferes y la fusión de datos del búfer de inserción.

SUGERENCIA # 2

Para separar datos e índices del espacio de tabla del sistema (ibdata1), debe realizar una reestructuración completa de InnoDB. Suena complicado, pero es muy sencillo. Escribí sobre esto en el DBA StackExchange (29 de agosto de 2012) y en StackOverflow (29 de octubre de 2010) . Los pasos básicos son

  • correr SET GLOBAL innodb_fast_shutdown = 0;
  • mysqldump todos los datos a un volcado de SQL
  • service mysql stop
  • Eliminar los siguientes archivos
    • ibdata1
    • ib_logfile0
    • ib_logfile1
  • service mysql start

Antes de correr service mysql start, agregue esta línea amy.cnf

innodb_open_files=32768

De esa manera, habrá identificadores de archivos dedicados a cada tabla individual. El valor predeterminado es 300. Se sabe que los identificadores de archivo se almacenan en caché. Habrá una desaceleración si establece esto muy alto y golpea el techo rápidamente . Este no debería ser el caso si está trabajando una pequeña cantidad de tablas.

RolandoMySQLDBA
fuente
Gracias por tus sugerencias. Voy a tratar sugerencia # 2 en este momento, y voy a ajustar innodb_read_io_threads, innodb_write_io_threadsy `innodb_io_capacity'.
inohiro
"Eliminar los siguientes archivos ibdata1" Sheesh, sin previo aviso.
magallanes
6

Hay un documento completo dedicado a la carga masiva de datos en InnoDB. Los puntos principales:

  1. deshabilite la confirmación automática para evitar una descarga de registro adicional para cada instrucción de inserción: SET autocommit=0;...sql import;COMMIT;
  2. deshabilitar las comprobaciones externas y únicas (no puede deshabilitar todos los índices por completo)

    SET unique_checks=0;
    SET foreign_key_checks=0;
  3. Potencialmente establezca innodb_autoinc_lock_mode en 2, en lugar de 1 (el valor predeterminado). Aquí está la documentación sobre esta configuración.

El tercero puede ayudarlo o no, por lo que le sugiero leer ese enlace para ver cómo está cargando los datos inicialmente. Por ejemplo, si está dividiendo las cargas en múltiples inserciones para que se ejecuten simultáneamente, definitivamente le ayudará a establecer el valor en 2. Si está haciendo una inserción grande de varias líneas, no hará mucho (si es que hay algo) para ayuda.

Dado que está convirtiendo el registro binario para esta inserción inicial, no debe preocuparse por los espacios en los números de incremento automático (si se realizan inserciones concurrentes).

Derek Downey
fuente
¡Gracias por su respuesta! La inserción masiva se ve muy rápido, y lo intentaré más tarde.
inohiro
Simplemente configurando autocommit = 0 aumentado aunque puesto por órdenes de magnitud. ¡Gracias!
Alex Barker
1

Puede usar los siguientes métodos para acelerar las inserciones:

  • Si está insertando muchas filas desde el mismo cliente al mismo tiempo, use INSERTdeclaraciones con varias VALUESlistas para insertar varias filas a la vez. Esto es considerablemente más rápido (muchas veces más rápido en algunos casos) que usar INSERTdeclaraciones de una sola fila por separado . Si está agregando datos a una tabla no vacía, puede ajustar la variable bulk_insert_buffer_size para que la inserción de datos sea aún más rápida.
  • Al cargar una tabla desde un archivo de texto, use LOAD DATA INFILE. Esto suele ser 20 veces más rápido que usar INSERTdeclaraciones. Ver
  • Aproveche el hecho de que las columnas tienen valores predeterminados. Inserte valores explícitamente solo cuando el valor a insertar difiera del predeterminado. Esto reduce el análisis que debe hacer MySQL y mejora la velocidad de inserción.
  • Consulte la Sección 9.5.5, “ Carga masiva de datos para tablas de InnoDB ” para obtener consejos específicos para las tablas de InnoDB.
usuario2432735
fuente
0

Plan A: INSERTOS "Batch": varias filas por instrucción INSERT. Sugerir alrededor de 1000 filas por declaración. autocommit = encendido, no explícito COMIENZO ... COMPROMISO

Plan B: CARGAR DATOS

Si inserta demasiadas filas a la vez, InnoDB debe hacer más trabajo para poder deshacer la inserción si se produce un bloqueo. Por esta razón, no estoy de acuerdo con autocommit = off, que pondría todo el conjunto en una sola transacción.

CARGAR DATOS de todo el conjunto de filas puede tener el mismo problema, pero es bastante rápido.

buffer_pool = 5G de 6G está a punto de ser demasiado grande. Si hay algún intercambio, el rendimiento se desplomará.

PARTICIONAR probablemente lo haría ir más lento.

MOSTRAR CREAR TABLA: las claves secundarias podrían ser una desventaja grave.

¿Estás usando InnoDB? o XtraDB?

Rick James
fuente
Gracias por su respuesta. Estoy usando InnoDB. Prefiero que el Plan A al Plan B. LOAD DATAparezca tan rápido, pero necesitamos escribir datos en el texto a la vez como CSV, luego usar LOAD DATA¿no? / Voy a configurar el buffer_pool_sizea 4GB.
inohiro