Mysql

如何改進 AWS 的 RDS 中的插入?

  • March 28, 2018

我在 AWS 中有一個 MySQL db.t2.small,伺服器不在我的國家,但我得到了 70 毫秒。現在我需要在一個表中插入超過 7000 條記錄,但這需要很多時間,超過 6 分鐘。我嘗試了很多配置:

-query_cache_size=16777216
-query_cache_type=1
-net_write_timeout=300
-max_allowed_pa​​cket=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”是一樣的,只是替換addBatchexecuteUpdate();.

一個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 載入。它專為清潔和快速載入而設計。

引用自:https://dba.stackexchange.com/questions/152627