Dans ma candidature, mes INSERT semblent prendre une grande partie du temps. J'ai un grand nombre d'objets en mémoire (~ 40-50 000) que je souhaite insérer dans une table.
Prenons un exemple de table
CREATE TABLE bill (
id BIGINT(20) PRIMARY KEY,
amount INT(11) DEFAULT 0,
bill_date DATETIME DEFAULT NOW(),
INDEX (bill_date)
) ENGINE=InnoDB
En prenant 3 lignes comme taille de lot, voici les approches auxquelles je pourrais penser pour insérer
Approche 1 - construire et cuire 3 inserts bruts
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');
Approche 2 - regrouper les valeurs en 1 requête
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');
Approche 3 - lancer cette requête 1 fois en passant 6 paramètres
INSERT INTO bill (amount, bill_date) VALUES
(?, ?), (?, ?), (?, ?);
Approche 4 - Lancer cette requête préparée 3 fois en changeant les 2 paramètres à chaque fois
INSERT INTO bill (amount, bill_date) VALUES (?, ?);
Toute autre approche est la bienvenue.
Ma question est
Quelle est la façon la plus rapide de créer plusieurs insertions dans une table?
J'ai lu ce lien sur la vitesse d'insertion mysql et ce guide de programmation JDBC , mais je ne suis pas en mesure de conclure.
Mon cas -
Actuellement, ma table a environ 20 colonnes, dont la plupart sont des nombres, avec quelques varchar (60) et 1 colonne de texte. Mysql version 5.5. Fonctionnant sur INNODB et possède 1 index sur les clés primaires entières. Toutes les requêtes s'exécutent en transaction.
Je construis mes requêtes à partir de Java et j'utilise Spring JDBC pour exécuter les requêtes.
Je suis actuellement en train de suivre l'approche 3, cela prend environ 10 secondes pour 20 000 insertions dans une table vide, sans compter le temps nécessaire pour construire la requête.
Pour garder les choses en perspective, il faut 100 à 200 millis pour récupérer les données de la table.
Y a-t-il quelque chose qui me manque? Comment accélérer les inserts?
Réponses:
Pensez à regrouper vos commits. Une taille de lot de 1024 est une bonne taille de départ. Modifiez la taille des lots jusqu'à atteindre votre débit optimal.
la source
Avez-vous testé ou serait-il possible de supprimer des index sur la ou les tables de base de données de destination dans lesquelles vous les insérez, de les insérer dans des blocs plus petits (optimaux comme indiqué ci-dessus), puis de reconstruire les index sur la ou les tables de destination une fois tous les inserts terminés? Peut être quelque chose d'assez facile à tester pour confirmer.
la source
Certains conseils de chargement de données en masse à partir du document mysql peuvent être utiles. https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html
Vous pouvez augmenter la vitesse d'insertion de plusieurs manières:
J'espère que cette aide!
la source