Mysql
如何改進 AWS 的 RDS 中的插入?
我在 AWS 中有一個 MySQL db.t2.small,伺服器不在我的國家,但我得到了 70 毫秒。現在我需要在一個表中插入超過 7000 條記錄,但這需要很多時間,超過 6 分鐘。我嘗試了很多配置:
-query_cache_size=16777216 -query_cache_type=1 -net_write_timeout=300 -max_allowed_packet=536870912 -innodb_lock_wait_timeout=3600 -innodb_flush_log_at_trx_commit=2 (我也嘗試將其設置為 0)。
我嘗試逐個發送請求並使用批量發送,但結果是相同的,幾乎每秒插入 20 次。
我錯過了什麼?
我的 Java 批量程式碼:
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(); }
我從https://www.mkyong.com/jdbc/jdbc-preparedstatement-example-batch-update/拿了一些東西
我的“1 by 1”是一樣的,只是替換
addBatch
為executeUpdate();
.一個
SELECT 1;
查詢需要 0.059 秒。
有兩種方法可以有效(閱讀:快速)載入 7000 行。
LOAD DATA INFILE
– 在您建構了一個 7000 行的 CSV 文件之後。- “批處理”
INSERT
——比如INSERT INTO t (a,b) VALUES (1,2),(5,6),(9,2), ...;
——注意行數。100 到 1000 次是一個很好的範圍。
max_allowed_packet=536870912
– 不,不是在一個2GB的*小虛擬機中;*改為16M。其他可能要檢查的設置:key_buffer_size = 10M innodb_buffer_pool_size = 200M
我假設你的表是 InnoDB?
如果您在 RDS(不是您自己建構的 EC2 實例)中執行,您可以從 AWS Data Pipeline 工具中獲得出色的性能——直接從 S3 載入。它專為清潔和快速載入而設計。