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

推薦する

jsを使用して簡単なスネークゲームを書く

この記事では、参考までに、jsで書かれたシンプルなスネークゲームの具体的なコードを紹介します。具体的...

ウェブページエクスペリエンス: 計画と設計

1. デザインの方向性を明確にする<br />まず、どのユーザーを対象にデザインするのか...

ウェブページ制作と饅頭の関係(体験の共有)

昨日は遅くまで寝ていて、一日中起きていました。私の年齢では、夜更かしして本を書くのはもう無理のようで...

Vue ファースト スクリーン パフォーマンス最適化コンポーネントの知識ポイントの概要

Vue ファースト スクリーン パフォーマンス最適化コンポーネントVue ファースト スクリーン パ...

JavaScriptの基本的なインタラクションの詳細な説明

目次1. 要素の入手方法文書から入手ID取得クラス名 (className) を取得します。タグ名 ...

ウェブサイトの高速化における CDN、SCDN、DCDN の違いは何ですか?どうやって選ぶ?

1. CDNこれは、Web サイト上で最もよく使用される加速機能です。分散サーバー レイアウトによ...

Webデザイナーの成長体験

<br />まず最初に、私はこのグループの中では完全な新人だということを述べなければなり...

Linux システムで IPv6 をサポートするように Nginx を設定する方法

1. 既存のnginxがipv6をサポートしているかどうかを確認する既存の nginx が ipv6...

自己終了XHTMLタグを書くときに注意すべきこと

XHTMLの img タグは、次のように記述する必要があります: <img alt="...

Linux システムで tcpdump を使用してパケットをキャプチャする方法

まずサンプルコードを見てみましょう: 1. 共通パラメータ tcpdump -i eth0 -nn ...

Ubuntu 19.10 で ssh サービスを有効にする (詳細なプロセス)

Ubuntuでsshを開くのに1時間以上かかりました。主な原因は、最初に読んだチュートリアルの手順...

Linuxホスト名変更コマンドの詳しい説明

Linux ホスト名変更コマンド1. ホスト名を一時的に変更するだけの場合は、hostname コマ...

WeChat アプレット計算機の例

WeChatアプレット計算機の例、参考までに、具体的な内容は次のとおりです。インデックス.wxml ...

発生したブラウザの互換性の問題と解決策(推奨)について

序文:先週の日曜日、先輩から3ページ作るのを手伝って欲しいと頼まれました。データのやり取りなどはなく...

SQLはROW_NUMBER() OVER関数を使用してシーケンス番号を生成します。

構文: ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY...