¿Por qué es 'LOAD DATA INFILE' más rápido que las declaraciones INSERT normales?


22

He leído un artículo que menciona que podemos lograr 60,000 inserciones por segundo usando la LOAD DATA IN FILEinstrucción, que lee de archivos csv e inserta los datos en una base de datos.

¿Por qué debería diferir de los insertos normales?

EDITAR:
reduje el viaje de ida y vuelta llamando a una sola INSERTdeclaración:

INSERT INTO tblname
VALUES (NULL,2,'some text here0'),(NULL,2,'some text here1')
    ,(NULL,2,'some text here2'),(NULL,2,'some text here3')
    .....,(NULL,2,'some text here3000');

¿Qué hay de esto?


Escribí un artículo sobre Medio, comparando inserciones extendidas vs LOAD DATA INFILE: Inserciones de alta velocidad con MySQL . En pocas palabras: puede lograr el 65% del rendimiento del LOAD DATA INFILEuso de inserciones extendidas. Obtuve 240,000 insertos / segundo en hardware moderno.
Benjamin

Respuestas:


26

CARGAR DATOS DE DATOS e INSERTOS extendidos tienen sus distintas ventajas.

LOAD DATA INFILE está diseñado para la carga masiva de datos de la tabla en una sola operación junto con campanas y silbatos para realizar cosas como:

  • Saltar líneas iniciales
  • Saltar columnas específicas
  • Transformando columnas específicas
  • Carga de columnas específicas
  • Manejo de cuestiones clave duplicadas

Se necesita menos sobrecarga para analizar

Por otro lado, si solo importa 100 filas en lugar de 1,000,000 filas, INSERT extendido es sensato.

Tenga en cuenta que mysqldump se diseñó alrededor de INSERT extendidos en aras de llevar el diseño de la tabla junto con los datos, ya que realiza la inyección de cientos o miles de filas por INSERT. LOAD DATA INFILE siempre crea una dicotomía física entre el esquema y los datos.

Desde el punto de vista de la aplicación, LOAD DATA INFILE también es más insensible al cambio de esquema que los INSERT extendidos.

Uno puede ir y venir de lo bueno, lo malo y lo feo de usar LOAD DATA INFILE. Independientemente de la técnica que utilice, siempre debe establecer el tamaño de bulto_insertado_de_búfer . ¿Por qué?

De acuerdo con la documentación de MySQL en bulk_insert_buffer_size:

MyISAM usa un caché especial en forma de árbol para hacer insertos masivos más rápido para INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., y LOAD DATA INFILE cuando agrega datos a no vacío mesas. Esta variable limita el tamaño del árbol de caché en bytes por subproceso. Establecerlo en 0 deshabilita esta optimización. El valor predeterminado es 8 MB.

Durante años, he visto cliente tras cliente no configurar esto y dejarlo en 8 MB. Luego, cuando deciden usar LOAD DATA INFILE o importar mysqldumps, pueden sentir que algo anda mal. Por lo general, recomiendo configurar esto a un moderado 256M. En algunos casos, 512M.

Una vez que tenga un búfer INSERT masivo lo suficientemente grande, el uso de cualquiera de las técnicas se convierte en académico y se reduce a la elección personal. Para aplicaciones en las que inserta INSERT de forma masiva solo 100 filas bajo demanda, quédese con INSERTs extendidos.

Para ser justos, decir LOAD DATA INFILE es más rápido que las declaraciones INSERT normales es una especie de declaración cargada principalmente porque la configuración no se tiene en cuenta. Incluso si configura un punto de referencia entre LOAD DATA INFILE y los INSERT extendidos con un tamaño adecuado de bulk_insert_buffer_size, los nanosegundos guardados al analizar cada fila solo pueden producir resultados nominales en el mejor de los casos a favor de LOAD DATA INFILE.

Continúe y agregue esto a my.cnf

[mysqld]
bulk_inset_buffer_size=256M

También puede configurarlo solo para su sesión antes de lanzar INSERTs extendidos

SET bulk_insert_buffer_size= 1024 * 1024 * 256;

ACTUALIZACIÓN 2012-07-19 14:58 EDT

Para mantener las cosas en perspectiva, el búfer de inserción masiva solo es útil para cargar tablas MyISAM, no InnoDB. Escribí una publicación más reciente sobre la carga masiva de InnoDB: la carga de Mysql desde el archivo atascado esperando en el disco duro


4

La mayoría de los sistemas de administración de bases de datos tienen una instalación de carga masiva para cargar grandes volúmenes de datos rápidamente. Una INSERTdeclaración tiene una cantidad significativa de equipaje por declaración: bloqueo, demarcación de transacciones, comprobaciones de integridad referencial, asignación de recursos, E / S que debe hacerse por declaración.

Las operaciones de inserción masiva simplifican el proceso, por lo que este material tiene mucha, mucho menos sobrecarga por fila. Un DBMS puede cargar en masa pedidos de datos de magnitud más rápido que a través de instrucciones de inserción.


3

Analizar y ejecutar INSERTdeclaraciones individuales conlleva una sobrecarga mucho mayor que dividir un archivo CSV en columnas y cargarlas directamente.

Cada INSERTdeclaración debe ser analizada individualmente por el motor MySQL y verificada su validez; esto consume recursos adicionales de la CPU y también requiere más viajes de ida y vuelta del servidor cliente <>. Esto no necesita suceder cuando se realiza una carga masiva a través de LOAD DATA INFILE. También hay optimizaciones que pueden tener lugar cuando se usa LOAD DATA INFILEpara cargar en una tabla vacía. Vea este enlace para más información.


vea la parte EDITAR de mi pregunta.
ALH

Tenga en cuenta que no hay gastos generales de análisis cuando se utilizan declaraciones preparadas.
Benjamin
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.