.Net Core を使用して数千万のデータを MySQL にインポートする手順

.Net Core を使用して数千万のデータを MySQL にインポートする手順

事前準備

テスト注文フォーム

テーブル「trade」を作成します(
  `id` VARCHAR(50) NULL デフォルト NULL COLLATE 'utf8_unicode_ci',
  `trade_no` VARCHAR(50) NULL デフォルト NULL COLLATE 'utf8_unicode_ci',
  ユニークインデックス `id` (`id`)、
  インデックス `trade_no` (`trade_no`)
)
コメント = '注文'
照合='utf8_unicode_ci'
エンジン=InnoDB;

テスト環境

オペレーティング システム: Windows 10 Professional

CPU: Intel(R) Core(TM) i7-8650U CPU @1.90GHZ 2.11GHZ

メモリ: 16G

MySQL バージョン: 5.7.26

実施方法:

1. 単一のデータを挿入する

これは最も一般的な方法で、ループを通じてデータを 1 つずつインポートします。この方法の明らかな欠点は、毎回データベースに接続する必要があることです。

実装コード:

//開始時刻 var startTime = DateTime.Now;
(var conn = new MySqlConnection(connsql)) を使用します
{
    接続を開きます。
​
    // 100,000 個のデータを挿入します for (var i = 0; i < 100000; i++)
    {
        //挿入 var sql = string.Format("insert into trade(id,trade_no) values('{0}','{1}');",
            Guid.NewGuid().ToString()、"trade_" + (i + 1)
            );
        var sqlComm = 新しい MySqlCommand();
        sqlComm.Connection は接続です。
        sqlComm.CommandText = sql;
        sqlComm.ExecuteNonQuery();
        sqlComm.Dispose();
    }
​
    接続を閉じる();
}
​
//完了時間 var endTime = DateTime.Now;
​
//時間がかかります var spanTime = endTime - startTime;
Console.WriteLine("ループ挿入メソッドには次の時間がかかります: " + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "ミリ秒");

100,000 回のテストには次の時間がかかります:

上記の例では、100,000 件のレコードをバッチでインポートしており、データベースに 100,000 回接続する必要があります。 SQL ステートメントを 1000 に変更し、それらを 1 つに連結することで、データベース接続を減らすことができます。コードは次のように変更されます。

//開始時刻 var startTime = DateTime.Now;
(var conn = new MySqlConnection(connsql)) を使用します
{
    接続を開きます。
​
    // 100,000 個のデータを挿入します var sql = new StringBuilder();
    (var i = 0; i < 100000; i++) の場合
    {
        //挿入 sql.AppendFormat("insert into trade(id,trade_no) values('{0}','{1}');",
            Guid.NewGuid().ToString()、"trade_" + (i + 1)
            );
​
        //マージして挿入 if (i % 1000 == 999)
        {
            var sqlComm = 新しい MySqlCommand();
            sqlComm.Connection は接続です。
            sqlComm.CommandText = sql.ToString();
            sqlComm.ExecuteNonQuery();
            sqlComm.Dispose();
            sql.Clear();
        }
    }
​
    接続を閉じる();
}
​
//完了時間 var endTime = DateTime.Now;
​
//時間がかかります var spanTime = endTime - startTime;
Console.WriteLine("ループ挿入メソッドには次の時間がかかります: " + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "ミリ秒");

100,000 回のテストには次の時間がかかります:

最適化後は、元々 100,000 回必要だったデータベース接続時間が 100 回の接続で済みます。最終的な動作結果から判断すると、データベースは同一サーバー上にあり、ネットワーク転送を伴わないため、パフォーマンスの向上は明らかではありません。

2. マージデータ挿入

MySQL は、データをマージすることによるバッチ データ インポートもサポートしています。実装コード:

//開始時刻 var startTime = DateTime.Now;
(var conn = new MySqlConnection(connsql)) を使用します
{
    接続を開きます。
​
    // 100,000 個のデータを挿入します var sql = new StringBuilder();
    (var i = 0; i < 100000; i++) の場合
    {
        (i % 1000 == 0)の場合
        {
            sql.Append("trade(id,trade_no) の値に挿入");
        }
​
        // 連結 sql.AppendFormat("('{0}','{1}'),", Guid.NewGuid().ToString(), "trade_" + (i + 1));
​
        // 一度に 1000 件のレコードを挿入します if (i % 1000 == 999)
        {
            var sqlComm = 新しい MySqlCommand();
            sqlComm.Connection は接続です。
            sqlComm.CommandText = sql.ToString().TrimEnd(',');
            sqlComm.ExecuteNonQuery();
            sqlComm.Dispose();
            sql.Clear();
        }
    }

        ​
    接続を閉じる();
}
​
//完了時間 var endTime = DateTime.Now;
​
//時間がかかります var spanTime = endTime - startTime;
Console.WriteLine("マージ データ挿入メソッドには時間がかかります: " + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "ミリ秒");

100,000 回のテストには次の時間がかかります:

このように操作を挿入すると、プログラムの挿入効率が大幅に向上します。最初の方法でも最適化後のデータベース接続数を減らすことができますが、2 番目の方法ではマージ後のログの量 (MySQL binlog と innodb トランザクション ログ) が減り、ログ フラッシュの量と頻度が減るため、効率が向上します。同時に、SQL ステートメントの解析回数を減らし、ネットワーク転送 IO を削減することもできます。

3. MySqlBulkLoader 挿入

MySQLBulkLoader は LOAD DATA INFILE とも呼ばれます。その原理はファイルからデータを読み取ることです。したがって、データセットをファイルに保存し、ファイルから読み取る必要があります。

実装コード:

//開始時刻 var startTime = DateTime.Now;
(var conn = new MySqlConnection(connsql)) を使用します
{
    接続を開きます。
    var テーブル = 新しい DataTable();
    table.Columns.Add("id", typeof(string));
    table.Columns.Add("trade_no", typeof(string));
​
    // 100,000 個のデータを生成する (var i = 0; i < 100000; i++)
    {
        (i % 500000 == 0)の場合
        {
            テーブル行をクリアします。
        }
​
        //レコード var row = table.NewRow();
        行[0] = Guid.NewGuid().ToString();
        行[1] = "trade_" + (i + 1);
        テーブルに行を追加します。
​
        // 500,000 件のレコードを一括で挿入します if (i % 500000 != 499999 && i < (100000 - 1))
        {
            続く;
        }
        Console.WriteLine("挿入を開始します: " + i);
​
        //データをcsv形式に変換します。var tradeCsv = DataTableToCsv(table);
        var tradeFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "trade.csv";
        File.WriteAllText(tradeFilePath、tradeCsv);
​
        #region データベースに保存 var bulkCopy = new MySqlBulkLoader(conn)
        {
            フィールドターミネータ = ",",
            フィールド引用文字 = '"',
            エスケープ文字 = '"',
            行終端文字 = "\r\n",
            ファイル名 = tradeFilePath、
            スキップする行数 = 0、
            テーブル名 = "trade"
        };
​
        bulkCopy.Columns.AddRange(table.Columns.Cast<DataColumn>().Select(colum => column.ColumnName).ToList());
        一括コピー.Load();
        #終了領域
    }
​
    接続を閉じる();
}
​
//完了時間 var endTime = DateTime.Now;
​
//時間がかかります var spanTime = endTime - startTime;
Console.WriteLine("MySqlBulk メソッドには、" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "ミリ秒" かかります);

100,000 回のテストには次の時間がかかります:

注: MySQL データベース構成を有効にする必要があります: ファイルのインポートを許可します。構成は次のとおりです。

secure_file_priv=

パフォーマンステストの比較

上記の 3 つの方法では、それぞれ 10 万、20 万、100 万、1,000 万のデータ レコードがテストされ、最終的なパフォーマンスは次のようになりました。

やっと

テスト データによると、データ量が増えると、MySqlBulkLoader メソッドのパフォーマンスは依然として良好ですが、他のメソッドのパフォーマンスは大幅に低下します。 MySqlBulkLoader メソッドは、私たちのニーズを完全に満たすことができます。

上記は、.Net Core が数千万のデータを Mysql にインポートする手順の詳細な内容です。数千万のデータを Mysql にインポートする方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • .Net Core は数千万のデータを MySQL データベースにインポートします
  • MySQLデータベースの数千万件のデータクエリとストレージの詳細な説明
  • インデックスを使用して数千万のデータを持つ MySQL のクエリ速度を最適化する
  • MySQLループは数千万のデータを挿入する
  • 数千万のMySQLデータ量を素早くページ分割する方法
  • 数千万のデータを扱うMySQLのページングクエリのパフォーマンスを最適化する
  • 数千万のデータを含む MySQL テーブルを最適化するにはどうすればよいでしょうか?
  • 単一の MySQL テーブルで数千万のデータを処理するアイデアを共有する

<<:  Web ページ WB.ExecWB 制御印刷メソッド呼び出しの説明とパラメータの紹介

>>:  CN2、GIA、CIA、BGP、IPLC はどういう意味ですか?

推薦する

Dockerを使用してSpring Bootプロジェクトをデプロイする手順

目次シンプルなSpringbootプロジェクトを作成する1. pom.xmlでSpring Boot...

C++ TpeScriptシリーズのジェネリックについて

目次1. テンプレート2. ジェネリック3. ジェネリック再帰4. デフォルトのジェネリックパラメー...

vitrualBox+ubuntu16.04 python3.6 最新チュートリアルと詳細な手順のインストール

最近ディープラーニングを学ぶためにUbuntu+Python 3.6バージョンを使う必要があるため、...

CSS のフローティング サンプル コードをクリアする方法

概要この記事のフレームワーク図は次のとおりです。 1. フローティングとは一体何でしょうか? W3s...

HTML で div+CSS を使用してシンプルな矢印アイコンを実装するコード

ウェブデザインでは、ウェブページを美しく見せるために矢印を装飾としてよく使用します。現在、多くのウェ...

MySQLデータベースとテーブルシャーディングの概要

プロジェクトの開発中に、データベースのデータがどんどん大きくなり、その結果、1 つのテーブルにデータ...

Puppeteer を使用して Linux (CentOS) で Web ページのスクリーンショット機能を実装する

Linux に puppeteer をインストールするときに、次の問題が発生する可能性があります。こ...

Vue.js プロジェクトの開始方法

目次1. Node.jsとVue 2. ローカル開発環境でフロントエンドのVueプロジェクトを実行す...

vue.config.js パッケージ最適化構成

Baiduの情報は多様すぎて目が回ります。心配しないでください。私はあなたのためにそれを体験しました...

Javascript 構造化代入の詳細

目次1. 配列の分解2. オブジェクトの分解3. 不完全な解体4. 分割代入を使用して変数交換を実装...

dockerカスタムイメージでphp7をビルドする方法

まず、簡単な Docker インストールを実行します。イメージをカスタマイズするには、ベースイメージ...

MySQL の結合テーブルにインデックスを作成する方法

この記事では、MySQL で 2 つのテーブルを関連付ける結合テーブルにインデックスを作成する方法を...

HTMLはシンプルで美しいログインページを作成します

まずは見てみましょう。 HTML ソースコード: XML/HTML コードコンテンツをクリップボード...

docker の実行に必要な権限の分析

Docker を実行するには root 権限が必要です。非 root ユーザーに docker コマ...