Inserisci velocità per lotti di grandi dimensioni


10

Nella mia applicazione, i miei INSERT sembrano prendere un pezzo grosso del tempo. Ho un gran numero di oggetti in memoria (~ 40-50.000) che voglio inserire in una tabella.

Consente di prendere una tabella di esempio

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

Prendendo 3 righe come dimensione del mio batch, i seguenti sono gli approcci che potrei pensare di inserire

Approccio 1: costruire e sparare 3 inserti grezzi

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');

Approccio 2: clubbing dei valori in 1 query

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');

Approccio 3: attiva questa query 1 volta passando 6 parametri

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

Approccio 4: attiva questa query preparata 3 volte modificando i 2 parametri ogni volta

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

Qualsiasi altro approccio è il benvenuto.

La mia domanda è

Qual è il modo più rapido per creare più inserti in una tabella?

Ho letto questo link su mysql insert speed e questa guida alla programmazione JDBC , ma non sono in grado di giungere a una conclusione.

Il mio caso -

Attualmente la mia tabella ha ~ 20 colonne, la maggior parte delle quali sono numeri, con un paio di varchar (60) e 1 colonna di testo. Mysql versione 5.5. In esecuzione su INNODB e ha 1 indice su chiavi primarie Integer. Tutte le query vengono eseguite nella transazione.

Costruisco le mie query da Java e utilizzo Spring JDBC per eseguire le query.

Attualmente sto seguendo l'approccio 3, ci vogliono circa 10 secondi per 20.000 inserimenti su una tabella vuota, senza includere il tempo necessario per costruire la query.

Per mantenere le cose in prospettiva, ci vogliono 100-200 millis per recuperare i dati dalla tabella.

C'è qualcosa che mi manca? Come si velocizzano gli inserti?


Risposte:


3

Valuta di raggruppare i tuoi commit. Una dimensione in lotti di 1024 è una buona dimensione iniziale. Modificare le dimensioni dei lotti fino a raggiungere la produttività ottimale.


1

Hai eseguito il test o sarebbe possibile eliminare gli indici nelle tabelle DB di destinazione in cui stai inserendo, inserirli in blocchi batch più piccoli (ottimali come indicato sopra), quindi ricostruire gli indici nelle tabelle di destinazione una volta che tutti gli inserti sono completi? Potrebbe essere qualcosa di abbastanza facile da testare per confermare.


0

Alcuni suggerimenti per il caricamento di dati in blocco dal documento mysql sono utili. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

È possibile aumentare la velocità di inserimento in alcuni modi:

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

Spero che questo aiuto!


2
Se si disattivano i controlli dei vincoli (univoci, chiave esterna, ...) assicurarsi che i dati non li rompano o che il database si trovi in ​​uno stato incoerente da quel momento in poi.
David Spillett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.