MySQL での IN データボリュームの使用の最適化された記録

MySQL での IN データボリュームの使用の最適化された記録

MySQL のバージョン番号は 5.7.28 です。テーブル A には 390 万件のレコードがあり、InnoDB エンジンを使用しています。varchar 型フィールド mac は、B ツリーを使用してインデックス化されています。テーブル B には 5000 件以上のレコードしかありません。

次のように記述された SQL 命令があります。

SELECT * FROM A WHERE mac IN("aa:aa:aa:aa:aa:aa","bb:bb:bb:bb:bb:bb:b",...900 を超えるエントリは省略)

クエリを通じて結果を取得するのに 294.428 秒かかりました。はい、約5分です。

EXPLAIN を使用して分析します。

アクセス タイプは範囲で、インデックスがヒットしましたが、行数は 587776 行しかありません。クエリに時間がかかるのはなぜですか?

mac のインデックス方法は B-tree を使用します。これを HASH と比較して簡単にまとめると、B-tree インデックスは =、>、>=、<、<= と計算間に使用できますが、HASH は等価演算しか実行できず、範囲検索は実行できません。この場合、IN は同等の操作となり、両方のインデックス作成方法を適用できます。この場合、mac のインデックス方式を HASH に変更すると、同じクエリに時間がかかります。

インデックス メソッドを調整してもステートメントのクエリ パフォーマンスを大幅に向上させることはできないため、ステートメント自体からのみ処理できます。実際、洞察力のある人なら誰でも一目見て SELECT * が非常にパフォーマンスを消費することがわかります。そのため、ビジネスに必要なフィールドのみをクエリし、ステートメントを次のように調整します。

SELECT id,mileage FROM A WHERE mac IN("aa:aa:aa:aa:aa:aa","bb:bb:bb:bb:bb:bb:b",...900 を超えるエントリは省略)

時間の消費量に大きな増加はありません。

IN メソッドは最適化が非常に難しいため、LEFT JOIN の使用をあきらめてもよいでしょうか?声明は次のように調整されます。

a.id、a.mileage を A から選択し、a LEFT JOIN B b ON b.mac = a.mac WHERE b.create_time >= '2020-01-01' とします。

5 分以上かかる場合は諦めてください。

条件の数が少ない場合、EXISTS と IN の効果に明らかな違いがないことがわかります。しかし、条件が多数ある場合は、EXISTS よりも IN の方が効率的です。EXISTS を試してみましょう。

SELECT id,mileage FROM A a WHERE EXISTS(SELECT mac FROM B WHERE create_time >= '2020-01-01' AND mac = a.mac)

これも5分以上かかります。確かにEXISTSよりもINの方が効率的なので諦めました。

したがって、最終的な結論としては、IN の後に大量のデータを含む文字列が続く場合は注意する必要がある、ということです。

このプロジェクトでは、mac を一意の識別子として使用し、id を持つ対応するテーブルを作成します。テーブル A では、mac の代わりに mac_id が使用され、クエリ時に IN(1,2,3...) が使用されます。効率が向上します。現在はNoSQLを使うのも一つの方法です。

要約する

大量データ用に IN を使用して MySQL を最適化する方法については、これで終わりです。大量データ用に IN を使用して MySQL を最適化する方法についての詳細は、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MYSQL IN と EXISTS の最適化の例
  • MySQL の not in と minus の最適化
  • MySqlを最適化するためにnot inを使用する方法
  • MySQL における or、in、union、インデックス最適化の詳細な分析
  • サブクエリ最適化における MySQL 選択の実装

<<:  Web プロジェクト開発 VUE の混合と継承の原則

>>:  Linux で libudev を使用して USB デバイスの VID と PID を取得する方法

推薦する

Reactソースコードにおけるビット演算について詳しく説明します

目次序文いくつかの一般的なビット操作ビットAND (&)ビットOR (|)ビット否定(~)マ...

yum インストールエラーの問題を解決する 保護されたマルチライブラリバージョン

現在、クラウドサーバーに nginx をインストールする際、最初に zlib などの依存ライブラリを...

Dockerイメージのローカル移行の実装

最近 Docker を勉強しているのですが、よく問題に遭遇します。Docker イメージをダウンロー...

MySQL インデックスの最適化: ページング探索の詳細な紹介

目次MySQL インデックス最適化ページングの調査ケース1ケース2 MySQL インデックス最適化ペ...

Centos7 での Rsync+crontab 定期同期バックアップ

最近、社内の重要なサーバデータを定期的にストレージにバックアップし、ついでにメモしておきたい以前、W...

CSSはクーポンスタイルを実装するために放射状グラデーションを使用します

この記事では、CSS で放射状グラデーションを使用して、次の図に示すクーポン スタイルの効果を実現す...

モバイルウェブ画面適応(rem)

序文最近、フロントエンドの学習に関する以前のメモを整理したところ、モバイル Web 画面の適応 (r...

CSSはcalc()を使用して現在の表示画面の高さを取得します

まず、CSS3 の相対的な長さの単位を見てみましょう (詳細なチュートリアルを参照してください)。相...

MySQL データ ウェアハウスを保護するための 5 つのヒント

さまざまなソースからデータを集約することで、中央倉庫を作成できます。データ ウェアハウスは、ビジネス...

503 サービス利用不可エラーの解決方法の説明

1. Webページを開くと503サービス利用不可が表示されますが、更新すると正常にアクセスできます。...

MySQL マスタースレーブ同期メカニズムと同期遅延問題追跡プロセス

序文DBA として、仕事中に MySQL マスターとスレーブの同期遅延の問題に遭遇することがよくあり...

MySQLにおけるrow_numberの実装プロセス

1. 背景一般的に、データ ウェアハウス環境では、row_number 関数を使用して特定のディメン...

Vue のライフサイクルとフック関数

目次1.ライフサイクルとは何か2. Vueのライフサイクル3. ライフサイクルフック関数1.ライフサ...

MySQLクエリで大文字と小文字を区別しない問題を解決する方法

質問最近、SSH フレームワークを使用して実用的なプロジェクトを完了していたときに、長い間悩まされて...

Docker Enterprise Edition を使用して独自のプライベート レジストリ サーバーを構築する

Docker は本当に素晴らしいです。特に、仮想マシンを使用する場合に比べて、Docker イメージ...