10秒以内にMySQLデータベースに数百万件のレコードを挿入する実装

10秒以内にMySQLデータベースに数百万件のレコードを挿入する実装

まず、次の質問について考えてみましょう。

このような膨大な量のデータをデータベースに挿入するには、通常の状況では頻繁にアクセスする必要があり、いかなる機械設備でも処理できません。では、データベースへの頻繁なアクセスを回避するにはどうすればよいでしょうか? 一度アクセスしてから実行することはできますか?

Java は実際に答えを与えてくれました。

ここでは、 StatementPrepareStatementという2つの主要なオブジェクトが使用されます。

2つの特徴を見てみましょう。

使用する BaseDao ツール クラス (jar パッケージ/Maven 依存関係) (Maven 依存関係コードは記事の最後に添付されています) (簡単に使用できるようにパッケージ化されています)

注意: (重要) rewriteBatchedStatements=true の場合、一度に複数のデータを挿入し、一度だけ挿入してください。 !

public class BaseDao { // 静的ツールクラス。データベース接続オブジェクトを作成し、簡単に呼び出せるようにリソースを解放するために使用されます // ドライバー jar パッケージをインポートするか、Maven 依存関係を追加します (ここでは Maven が使用され、Maven 依存関係コードは記事の最後に添付されています)
    静的{
        試す {
            クラス.forName("com.mysql.cj.jdbc.Driver");
        } キャッチ (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
 
    // データベース接続オブジェクトを取得する public static Connection getConn() {
        接続 conn = null;
        試す {
            // rewriteBatchedStatements=true、一度に複数のデータを挿入、一度だけ挿入conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/million-test?rewriteBatchedStatements=true", "root", "qwerdf");
        } catch (SQLException スロー可能) {
            throwables.printStackTrace();
        }
        conn を返します。
    }
 
    // リソースを解放する public static void closeAll(AutoCloseable... autoCloseables) {
        (AutoCloseable autoCloseable : autoCloseables) の場合 {
            自動クローズ可能 != null の場合 {
                試す {
                    自動クローズ可能。
                } キャッチ (例外 e) {
                    // TODO 自動生成されたキャッチブロック
                    e.printStackTrace();
                }
            }
        }
    }
}

次にキーコードとコメントを示します。

/* データベースの処理速度が非常に速いため、単一のスループットが非常に大きく、実行効率が非常に高くなります。addBatch() は、複数の SQL 文をまとめて読み込み、データベースに送信して一度に実行します。実行には非常に短い時間しかかかりません。preparedStatement.executeUpdate() は、それらを 1 つずつデータベースに送信して実行し、データベース接続の転送に時間がかかります。*/
パブリック静的voidメイン(String[] args) {
    long start = System.currentTimeMillis(); // メソッドの実行を開始する前に、システムの現在の時刻を取得して記録します。 Connection conn = BaseDao.getConn(); // 接続データベース オブジェクトを取得するために記述したばかりの静的ツール クラスを呼び出します。 String sql = "insert into mymilliontest values(null,?,?,?,NOW())"; // 実行される SQL ステートメント PreparedStatement ps = null;
    試す {
        ps = conn.prepareStatement(sql); // PreparedStatement オブジェクトを取得する // 継続的に sql を生成する
        (int i = 0; i < 1000000; i++) の場合 {
            ps.setString(1, Math.ceil(Math.random() * 1000000) + "");
            ps.setString(2, Math.ceil(Math.random() * 1000000) + "");
            ps.setString(3, UUID.randomUUID().toString()); // UUID クラスは、繰り返されない文字列をランダムに生成するために使用されます。 ps.addBatch(); // この PreparedStatement オブジェクトのバッチ コマンドに一連のパラメーターを追加します。
        }
        int[] ints = ps.executeBatch(); // 実行のためにコマンドのバッチをデータベースに送信します。すべてのコマンドが正常に実行されると、更新カウントの配列が返されます。
        // 配列の長さが 0 でない場合は、SQL ステートメントが正常に実行され、100 万個のデータが正常に追加されたことを意味します。
        (ints.length > 0)の場合{
            System.out.println("100 万件のレコードが正常に追加されました!!");
        }
    } catch (SQLException スロー可能) {
        throwables.printStackTrace();
    ついに
        BaseDao.closeAll(conn, ps); // リソースを解放するために記述した静的ツール クラスを呼び出します}
    long end = System.currentTimeMillis(); // システム時間を再度取得します System.out.println("所要時間: " + (end - start) / 1000 + "秒"); // 2 つの時間を減算すると、メソッドの実行にかかった時間になります}

最後に、実行して効果を確認しましょう。

ねえ、ここの持続時間は10秒以上です、装備が十分ではありません、ご理解いただければ幸いです〜

<!--データベースへの接続に使用されるmysql-connector-java依存関係-->
<依存関係>
    <グループID>mysql</グループID>
    <artifactId>mysql-コネクタ-java</artifactId>
    <バージョン>8.0.27</バージョン>
</依存関係>

PS: スレッドを追加するとさらに高速になります。後続の記事で例を示します。

これで、10 秒以内に 100 万件のレコードを MySQL データベースに挿入する方法についての説明は終わりです。MySQL に 100 万件のレコードを挿入する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQLは数百万のシミュレーションデータ操作コードを自動的に挿入します
  • 数百万のデータに対して MySQL クエリを最適化する 4 つの方法
  • MySQL 単一テーブル 100 万データ レコード ページング パフォーマンス最適化スキル
  • MySQLに何百万ものテストデータを素早く挿入する方法

<<:  Linux システムでのユーザー管理の概要

>>:  Vueでフォームデータを取得する方法

推薦する

Docker+gitlab+jenkins は、ゼロから自動デプロイメントを構築します

目次序文: 1. Dockerをインストールする2. DockerでJenkinsをインストールする...

Ubuntu 18.04で国内ソースを変更する方法の例

Ubuntu はソースが中国からなのでダウンロード速度が比較的遅いです。CentOS と異なり、yu...

複合主キーと複数列インデックスに遭遇した場合の MySQL 行ロックの詳細な説明

背景今日、他のプロジェクト チームと協力してシス​​テムのストレス テストを実施しているときに、プロ...

WeChatアプレットはキャンバスを使用して時計を描画します

この記事では、キャンバスを使用してWeChatアプレットに時計を描く具体的なコードを参考までに共有し...

CSS3 で半透明の背景画像と不透明なコンテンツを実現する方法の例

以前のブログのログインページを作成していたときに、この問題に遭遇しました。突然、透明な背景画像と不透...

Dockerボリューム権限管理の詳細な説明

ボリュームデータボリュームは Docker の重要な概念です。データ ボリュームは、1 つ以上のコン...

Vue でバイナリ ファイル ストリームを受信して​​ PDF プレビューを実現する方法

バックグラウンド コントローラー @RequestMapping("/getPDFStre...

ページコンテンツ全体を中央に配置して、高さがコンテンツに合わせて自動的に拡張されるようにする方法

ページコンテンツ全体を中央に配置する方法と、コンテンツに合わせて高さを自動的に拡大縮小する方法。これ...

MySQL データベース テーブルとデータベース パーティショニング戦略

まず、テーブルを分割する必要がある理由について説明します。データシートが数百万に達すると、1 回のク...

MySQL データベースのバックアップをスケジュールするいくつかの方法 (包括的)

目次1. データをバックアップするためのmysqldumpコマンド2. 一般的なmysqldump操...

CSS3でアニメーションを実装する3つの方法

これは、面接者の CSS に関する基本的な知識をテストするものです。 CSSでアニメーションを実装す...

Zabbixについて管理者ログインパスワードを忘れた場合、パスワードをリセットする

Zabbix 管理者ログイン パスワードのリセットに関する問題は次のとおりです。 1. 問題の説明:...

フレックスレイアウトは左のテキストオーバーフローを実現し、右のテキストの適応を省略します

テキストの長さに応じて、左側のテキストの幅を自動調整できる状況を実現したい。1行が表示できない場合、...

複数の条件を持つ MySQL クエリ メソッド

複数の条件を持つ MySQL クエリ環境: MySQL 5.7 where ステートメントに複数の ...

iOS、Android、ミニプログラムアプリの敷居の低い開発のためのフロントエンドフレームワークを詳しく解説

現在、クロスプラットフォーム開発技術はもはや新しい話題ではありません。市場にはいくつかのオープンソー...