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

推薦する

MySQL トリガーの基本的な使い方(作成、表示、削除など)の詳細な説明

目次1. MySQLトリガーの作成: 1. MySQLトリガー作成構文: 2. MySQL作成構文の...

MySQLのexplain型の詳細な説明

導入:多くの場合、さまざまな選択ステートメントを使用して必要なデータを照会した後、多くの人は作業が正...

JavaScriptコールバック関数の詳細な理解

目次序文クイックレビュー: JavaScript 関数関数とは何ですか?関数を宣言する関数の呼び出し...

HTML テーブルタグチュートリアル (12): 境界線スタイル属性 FRAME

FRAME プロパティを使用して、表の境界線のスタイル タイプを制御します。基本的な構文<T...

Ubuntu 20.04 に Python 3 仮想環境をインストールする詳細なチュートリアル

以下はすべて仮想マシン上で実行されます1. pip3をインストールするsudo apt で pyth...

純粋な CSS ヘッダーの実装コードを修正

純粋な CSS で固定ヘッダーを実装するのが難しい主な理由は 2 つあります。まず、最大のシェアを持...

MySQL設定ファイルを変更できない問題の解決方法(Win10)

他の人のために解決した問題を記録します。問題の説明MySQLのバージョンは5.7、オペレーティングシ...

MySQLに必要な共通知識のまとめ

目次主キー制約一意の主キー非 Null 制約デフォルトの制約外部キー制約1NF 2NF 3NFデータ...

Vueは遅延読み込みによりページの応答速度を向上

目次概要遅延読み込みとは何ですか?最適化を開始するビジネスモジュールを分割する遅延読み込みルート構成...

Linux で scp コマンドを使用してファイルをリモートでコピーする方法の詳細な説明

序文scp は secure copy の略です。scp は、Linux システムの ssh ログイ...

Vue 初心者ガイド: 環境の構築と開始方法

目次初期ビューVue開発環境の構築Vueインスタンスの作成Vue テンプレート構文Vue データバイ...

CentOS8 jdk8 / java8 のインストールチュートリアル(推奨)

序文最初はCentOS8でwgetを使ってダウンロードし、解凍して環境変数を設定するつもりだったので...

Mysql WorkBench のインストールと設定のグラフィックチュートリアル

この記事では、Mysql WorkBenchのインストールと設定のグラフィックチュートリアルを参考ま...

Vue.$set の失敗の落とし穴の発見と解決

偶然、プロジェクト内でVue.$setが無効であることがわかりましたデータ フィルタリングを追加する...

リクエスト数を制限するために Ajax 同時リクエストを実装するために js を使用するサンプル コード

問題の説明: 非同期リクエストの数が不確定な場合、数百の http リクエストが瞬時に発生したときに...