web-dev-qa-db-ja.com

AWSのRDSへの挿入を改善するにはどうすればよいですか?

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に設定してみました)。

リクエストを1つずつ送信し、バルクも使用してみましたが、結果は同じで、1秒あたり約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秒かかります。

3
Jebus

7000行を効率的に(読み取り:迅速に)ロードするには、2つの方法があります。

  • _LOAD DATA INFILE_-7000行のCSVファイルを作成した後。

  • 「バッチ」INSERT-INSERT INTO t (a,b) VALUES (1,2),(5,6),(9,2), ...;のように-行数に注意してください。 100から1000は、一度に実行するのに適した範囲です。

_max_allowed_packet=536870912_-いいえ、tiny 2GB VMにはありません。 16Mに変更します。チェックする可能性のあるその他の設定:

_key_buffer_size = 10M
innodb_buffer_pool_size = 200M
_

あなたのテーブルはInnoDBだと思いますか?

1
Rick James

RDS(独自にビルドしたEC2インスタンスではない)で実行している場合、AWS Data Pipelineツールから優れたパフォーマンスを得ることができます。S3から直接ロードします。クリーンで高速なロードを目的として設計されています。

0
Chris Johnson