MySQL バッチ SQL 挿入パフォーマンス最適化の詳細な説明

MySQL バッチ SQL 挿入パフォーマンス最適化の詳細な説明

大量のデータを扱うシステムの中には、クエリ効率の低さやデータの保存時間の長さといったデータベースの問題を抱えているものがあります。特にレポート システムの場合、データのインポートにかかる時間は 1 日に数時間、場合によっては 10 時間以上に及ぶこともあります。したがって、データベース挿入パフォーマンスを最適化することは理にかなっています。

MySQL innodb でいくつかのパフォーマンス テストを行った後、挿入効率を向上できるいくつかの方法を見つけました。参考までに。

1. 1 つの SQL ステートメントで複数のレコードを挿入します。

よく使用される挿入ステートメントは次のとおりです。

`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('0'、'userid_0'、'content_0'、0); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('1'、'userid_1'、'content_1'、1); 

変更後:

`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('0'、'userid_0'、'content_0'、0)、('1'、'userid_1'、'content_1'、1); 

挿入操作を修正すると、プログラムの挿入効率が向上します。ここで 2 番目の SQL の実行効率が高い主な理由は、マージ後のログの量 (MySQL の binlog と innodb のトランザクションがログを作成する) が削減され、ログのフラッシュの量と頻度が削減され、効率が向上したためです。 SQL 文をマージすることで、SQL 文の解析回数を減らし、ネットワーク転送の IO を削減できます。

以下は、単一データのインポートとインポート用の SQL ステートメントへの変換で、それぞれ 100、1,000、10,000 のデータ レコードをテストしたテスト比較データです。

2. トランザクション内で挿入処理を実行します。

挿入を次のように変更します。

トランザクションを開始します。 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('0'、'userid_0'、'content_0'、0); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('1'、'userid_1'、'content_1'、1); 
... 
専念; 

トランザクションを使用すると、データ挿入の効率が向上します。これは、INSERT 操作を実行するときに、MySQL が内部的にトランザクションを確立し、実際の挿入処理操作がトランザクション内で実行されるためです。トランザクションを使用すると、トランザクションの作成コストを削減でき、すべての挿入は実行後にコミットされます。

ここでは、レコード数が 100、1,000、10,000 の場合にトランザクションを使用しない場合とトランザクションを使用する場合のテスト比較も提供されます。

3. データが順番に挿入されます。

順序付きデータ挿入とは、挿入されたレコードが主キーに基づいて順序付けられることを意味します。たとえば、datetime はレコードの主キーです。

`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('1'、'userid_1'、'content_1'、1); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('0'、'userid_0'、'content_0'、0); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('2'、'userid_2'、'content_2'、2); 

変更後:

`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('0'、'userid_0'、'content_0'、0); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('1'、'userid_1'、'content_1'、1); 
`insert_table` に INSERT します (`datetime`、`uid`、`content`、`type`) 
  値 ('2'、'userid_2'、'content_2'、2); 

データベースはデータを挿入するときにインデックス データを維持する必要があるため、順序が正しくないレコードがあるとインデックスの維持コストが増加します。 innodb が使用する B+tree インデックスを参照できます。各レコードがインデックスの末尾に挿入されると、インデックスの配置効率が非常に高くなり、インデックスの調整は小さくなります。挿入されたレコードがインデックスの途中にある場合、B+tree を分割して結合する必要があり、これによりコンピューティング リソースがさらに消費され、挿入されたレコードのインデックス配置効率が低下します。データ量が大きい場合、ディスク操作が頻繁に発生します。

以下は、100、1,000、10,000、100,000、100 万のレコードを使用したランダム データとシーケンシャル データのパフォーマンス比較を示しています。

テスト結果から、最適化方法のパフォーマンスは向上しましたが、その改善はあまり明白ではありません。

総合的なパフォーマンステスト:

ここでは、上記の 3 つの方法を使用して INSERT 効率を最適化するテストを示します。

テスト結果から、データ量が少ない場合、データ+トランザクションをマージする方法のパフォーマンス向上が明らかであることがわかります。データ量が大きい場合(1000万以上)は、パフォーマンスが急激に低下します。これは、この時点でデータ量がinnodb_bufferの容量を超えるためです。各インデックス配置には、より多くのディスク読み取りおよび書き込み操作が含まれ、パフォーマンスが急激に低下します。データ + トランザクション + 順序付けされたデータをマージする方法は、データ量が数千万以上に達した場合でも、依然として良好なパフォーマンスを発揮します。データ量が大きい場合、順序付けされたデータのインデックス配置はより便利であり、ディスク上での頻繁な読み取りおよび書き込み操作を必要としないため、より高いパフォーマンスを維持できます。

注記:

1. SQL 文には長さの制限があります。同じ SQL でデータをマージする場合、SQL 文の長さは SQL の長さ制限を超えてはなりません。これは、max_allowed_pa​​cket 構成で変更できます。デフォルト値は 1M ですが、テスト中に 8M に変更されました。

2. トランザクションのサイズを制御する必要があります。トランザクションが大きすぎると、実行効率に影響する可能性があります。 MySQL には innodb_log_buffer_size 設定項目があります。この値を超えると、innodb データがディスクにフラッシュされ、効率が低下します。したがって、データがこの値に達する前にトランザクションをコミットする方がよい方法です。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL に大量のデータを挿入する 4 つの方法の例
  • MYSQL バッチ挿入データ実装コード
  • MySQL でバッチ挿入を実装してパフォーマンスを最適化するチュートリアル
  • ユニークインデックスを使用したMySQLバッチ挿入を回避する方法
  • MySQLは挿入を使用して複数のレコードを挿入し、データを一括で追加します。
  • MySQL バッチ挿入ループの詳細なサンプルコード
  • MySQL バッチデータ挿入スクリプト
  • MySql バッチ挿入の最適化 SQL 実行効率の例の詳細な説明
  • MySQLバッチは関数ストアドプロシージャを通じてデータを挿入します

<<:  Docker を使って LEMP 環境を素早く構築する方法の例

>>:  Reactにおける不変値の説明

推薦する

デザイン理論: デザインにおける階層

<br />原文: http://andymao.com/andy/post/80.ht...

MySQL 5.7.10 winx64 のインストールと設定方法のグラフィック チュートリアル (win10)

MySQL は比較的使いやすいリレーショナル データベースです。今日は、win10 システムを再イ...

MySQL データベースの基礎 SQL ウィンドウ関数の例の分析チュートリアル

目次導入導入集計関数 + over()ソート関数 + over() ntile() 関数 + ove...

Vue 仮想 DOM クイックスタート

目次仮想DOM仮想DOMとは何か仮想DOMの役割Vue の仮想 DOM vノードvNodeとはvNo...

Nginxはドメイン名のアクセス方法を定義しています

最近Nginxを構築しているのですが、ドメイン名でアクセスできません。 nginx 構成ファイル n...

JavaScriptの再帰の詳細

目次1. 再帰とは何ですか? 2. 再帰を使って数学の問題を解く1. 1 * 2 * 3 * 4 …...

docker+gitlab+gitlab-runnerの詳細なデプロイメント

環境サーバー: centos7クライアント: ウィンドウCentos7 に docker+gitla...

CSS3 フィルター属性の使い方の紹介

1. はじめにフロントエンドページのアニメーション効果を記述する場合、filter 属性は多かれ少な...

純粋な HTML+CSS でオリンピック リングを実装するためのサンプル コード

レンダリング コード - 青と黄色のリングを例に挙げます <div class="コ...

VMware で Centos7 ブリッジ ネットワークを構成する手順の詳細な説明

VMware仮想マシンでのCentos7ブリッジネットワーク構成の完全な手順は参考用です。具体的な内...

Nginx は動的と静的の分離を実装します 例の説明

ウェブサイトの解析を高速化するために、動的ページと静的ページを異なるサーバーで解析して、解析速度を向...

CSS3は三角形の連続拡大効果を実現します

1. CSS3の三角形は特殊効果でズームし続けます11.1 画像プレビュー 11.2 index.h...

JSはキャンバス技術を使用してeChartsの棒グラフを模倣します

Canvas は HTML5 の新しいタグです。js を使用して Canvas 描画 API を操作...

HTML Selectは、デフォルトの選択を設定するためにselected属性を使用します。

オプションに属性 selected = "selected" を追加すると、それ...

JavaScript関数の詳細な紹介

任意の数のステートメントを関数を通じてカプセル化することができ、いつでもどこでも呼び出して実行できま...