J'ai un mysql db.t2.small à AWS, le serveur n'est pas dans mon pays, mais j'obtiens 70ms. Maintenant, j'ai besoin d'insérer plus de 7 000 enregistrements dans une table, mais cela prend beaucoup, plus de 6 minutes. J'ai essayé de nombreuses configurations:
[.____] - Query_Cache_size = 16777216 [.____] - Query_cache_type = 1 [.____] - Net_write_timeout = 300 [ -innodb_flush_log_at_trx_commit = 2 (aussi j'ai essayé de la définir à 0).
J'ai essayé d'envoyer les demandes 1 de 1 et utilisez également en gros, mais le résultat est le même, près de 20 inserts par seconde.
Qu'est-ce que je rate?
Mon Java code groupé:
try {
conn = bd.getConectionAWS();
PreparedStatement stmt = null;
if (conn.getAutoCommit()) {
conn.setAutoCommit(false);
}
try {
String query = "INSERT INTO CONTRATO(Codigo,Nombre,IdEstado,DesEstado,FechaInicio,IndActivo,Activo,Descripcion,Cliente,Responsable) VALUES(?,?,?,?,?,?,?,?,?,?) \n"
+ " ON DUPLICATE KEY \n"
+ " UPDATE Nombre=?, IdEstado=?, idEstado=? ,DesEstado=? ,FechaInicio=?, IndActivo=?,Descripcion=?,Cliente=?,Responsable=?";
stmt = conn.prepareStatement(query);
for (Contrato contrato : listaDatos) {
stmt.setString(1, contrato.getCodigo());
stmt.setString(2, contrato.getNombre());
stmt.setInt(3, contrato.getIdEstado());
stmt.setString(4, contrato.getDesEstado());
stmt.setTimestamp(5, contrato.getFechaInicio());
stmt.setString(6, contrato.getIndActivo());
stmt.setString(7, contrato.getActivo());
stmt.setString(8, contrato.getDescripcion());
stmt.setString(9, contrato.getCliente());
stmt.setString(10, contrato.getResponsable());
stmt.setString(11, contrato.getNombre());
stmt.setInt(12, contrato.getIdEstado());
stmt.setString(13, contrato.getDesEstado());
stmt.setTimestamp(14, contrato.getFechaInicio());
stmt.setString(15, contrato.getIndActivo());
stmt.setString(16, contrato.getActivo());
stmt.setString(17, contrato.getDescripcion());
stmt.setString(18, contrato.getCliente());
stmt.setString(19, contrato.getResponsable());
// stmt.executeUpdate();
stmt.addBatch();
}
stmt.executeBatch();
conn.commit();
}
J'ai pris quelques choses à partir de - https://www.mkyong.com/jdbc/jdbc-preparationStatement-example-batch-update/
Mon "1 par 1" est le même, il suffit de remplacer addBatch
pour executeUpdate();
.
Une requête SELECT 1;
Prend 0,059Sec.
Il y a deux façons d'atteindre efficacement (lire: rapidement) charger 7000 lignes.
LOAD DATA INFILE
- Une fois que vous avez construit un fichier CSV de 7 000 lignes.
"Lot" INSERT
- comme INSERT INTO t (a,b) VALUES (1,2),(5,6),(9,2), ...;
- Soyez prudent du nombre de lignes. 100 à 1000 est une bonne gamme de ce qu'il faut faire à la fois.
max_allowed_packet=536870912
- Non, pas dans A minuscule 2 Go VM; changer à 16m. Autres paramètres probables de vérifier:
key_buffer_size = 10M
innodb_buffer_pool_size = 200M
Je suppose que vos tables sont innodub ??
Si vous courez dans RDS (pas votre propre instance EC2 construite), vous pouvez obtenir de grandes performances à partir de l'outil AWS Data Pipeline - Charces directement à partir de S3. Il est conçu pour le chargement propre et rapide.