Insertar velocidades para lotes grandes

10

En mi aplicación, mis INSERT parecen ocupar una parte importante del tiempo. Tengo una gran cantidad de objetos en la memoria (~ 40-50,000) que quiero insertar en una tabla.

Tomemos una tabla de muestra

CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB

Tomando 3 filas como mi tamaño de lote, los siguientes son los enfoques que podría pensar para insertar

Enfoque 1: construya y dispare 3 insertos crudos

INSERT INTO bill (amount, bill_date) VALUES (10, '2012-01-01 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (20, '2012-01-02 00:00:00');
INSERT INTO bill (amount, bill_date) VALUES (40, '2013-02-05 00:00:00');

Enfoque 2: agrupar los valores en 1 consulta

INSERT INTO bill (amount, bill_date) VALUES 
(10, '2012-01-01 00:00:00'),
(20, '2012-01-02 00:00:00'),
(40, '2013-02-05 00:00:00');

Enfoque 3: active esta consulta 1 vez pasando 6 parámetros

INSERT INTO bill (amount, bill_date) VALUES 
(?, ?), (?, ?), (?, ?);

Enfoque 4: active esta consulta preparada 3 veces cambiando los 2 parámetros cada vez

INSERT INTO bill (amount, bill_date) VALUES (?, ?);

Cualquier otro enfoque es bienvenido.

Mi pregunta es

¿Cuál es la forma más rápida de hacer múltiples inserciones en una tabla?

He leído este enlace sobre la velocidad de inserción de mysql y esta guía de programación JDBC , pero no puedo llegar a una conclusión.

Mi caso -

Actualmente mi tabla tiene ~ 20 columnas, la mayoría de las cuales son números, con un par de varchar (60) y 1 columna de texto. Mysql versión 5.5. Se ejecuta en INNODB y tiene 1 índice en las claves primarias de enteros. Todas las consultas se ejecutan en la transacción.

Construyo mis consultas desde Java y uso Spring JDBC para ejecutar las consultas.

Actualmente estoy siguiendo el Enfoque 3, está tomando alrededor de 10 segundos para 20,000 inserciones en una tabla vacía, sin incluir el tiempo que lleva construir la consulta.

Para mantener las cosas en perspectiva, se necesitan entre 100 y 200 milis para obtener los datos de la tabla.

Hay algo que este olvidando? ¿Como hago los insertos más rápido?

Aditya
fuente
Pregunta relacionada sobre Stack Overflow: MySQL y JDBC con rewriteBatchedStatements = true
Gord Thompson el

Respuestas:

3

Considere agrupar sus confirmaciones. Un tamaño de lote de 1024 es un buen tamaño inicial. Cambie los tamaños de lote hasta alcanzar su rendimiento óptimo.

Rick Ryker
fuente
1

¿Ha probado o sería posible colocar índices en la (s) tabla (s) de base de datos de destino donde está insertando, insertarlos en fragmentos por lotes más pequeños (óptimo como se indicó anteriormente) y luego reconstruir los índices en la (s) tabla (s) de destino una vez que todos los insertos están completos? Puede ser algo bastante fácil de probar para confirmar.

Pimp Juice IT
fuente
0

Algunos consejos de carga de datos masivos del documento mysql son posibles útiles. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

Puede aumentar la velocidad de inserción de algunas maneras:

- turn off autocommit
- turn off unique check
- turn off foreign check

Espero que esto ayude !

Luke Nguyen
fuente
2
Si desactiva las comprobaciones de restricciones (clave externa única, ...), asegúrese de que sus datos no las rompan o que su base de datos esté en un estado inconsistente a partir de ese momento.
David Spillett