.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 はどういう意味ですか?

推薦する

Vueの監視プロパティの詳細

目次1.watchは一般的なデータ(数値、文字列、ブール値)の変更を監視します。 1. 数値2. 文...

学生情報管理システムを実装するためのJavaScript+HTML

目次1. はじめに2. レンダリング3. コード4. 学生情報管理システムのメインインターフェース1...

HTML マーキー文字フラグメントのスクロール

その特性は次のとおりです。方向アクティブな字幕のスクロール方向を設定するコードは次のとおりです。 &...

Vue3+Element+Tsは、フォームの基本的な検索リセットやその他の機能を実装します

Vue2 の記述スタイルから Vue3 の形式に切り替えると、記述スタイルとコード構造にいくつかの変...

正の整数かどうかを判断するMYSQLカスタム関数の例コード

関数を記述できます。主に正規表現を使用して判断を行います。入力文字が空の場合は、「-」を使用して置き...

JSホモロジー戦略とCSRFの詳細な説明

目次概要同一生成元ポリシー (SOP)相同制限クロスドメインをバイパスクロスサイトリクエストフォージ...

Javascript 文字列メソッドの詳細な説明

目次文字列の長さ: 長さcharAt() charCodeAt()文字列に値が含まれているかどうかを...

JavaScriptは検証コードと検証のランダム生成を実装します

この記事では、検証コードのランダム生成と検証を実現するためのJavaScriptの具体的なコードを参...

ログインと登録機能を実現するjs

この記事の例では、ログインと登録機能を実装するためのjsの具体的なコードを参考までに共有しています。...

Vueはドラッグ可能なツリー構造図を実装します

目次Vue 再帰コンポーネントドラッグイベント最近、Vue を使用して、ドラッグ可能なツリー構造図と...

JavaScript を使用してソートアルゴリズムを実装する方法

目次バブルソート選択ソート挿入ソート要約するバブルソートバブルソートは、シーケンスの右側から始めて、...

JavaScript での && および || 演算子の使用例

目次序文&& 演算子|| 演算子|| 演算子の簡単なデモ章の目的ケース演習(json...

nginx設定ファイルの解釈の詳細な説明

nginx 設定ファイルは主に 4 つの部分に分かれています。 main{#(グローバル設定) ht...

MySQL エラー「すべての派生テーブルには独自のエイリアスが必要です」の解決方法

MySQL は、マルチテーブルクエリを実行するときにエラーを報告します。 [SQL] SELECT ...

HTML で特定のテキストを非表示にするにはどうすればよいでしょうか?

テキスト非表示コード、HTML 内の特定のテキストを非表示にするコードをコピーコードは次のとおりです...