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 を取得する方法

推薦する

MySQL が innobackupex を使用して接続サーバーをバックアップできない場合の解決策

innobackupex を使用してバックアップする際に MySQL がサーバーに接続できない場合は...

VMware kali仮想マシン環境の設定方法

1|0 カーネルをコンパイルする(1)uname -rコマンドを実行してカーネルバージョンを表示しま...

CentOSはexpectを使用してスクリプトやコマンドをバッチでリモート実行します

サーバーへのファイルのアップロード、ソフトウェアのインストール、コマンドやスクリプトの実行、サービス...

mysql 8.0.19 winx64.zip インストール チュートリアル

この記事は参考までにmysql 8.0.19 winx64.zipのインストールチュートリアルを記録...

MySQL トランザクション分析

取引トランザクションはビジネス ロジックの基本単位です。各トランザクションは一連の SQL ステート...

Angular Cookie の読み取りおよび書き込み操作コード

Angular Cookie の読み取りおよび書き込み操作のコードは次のようになります。 var a...

CSSは高度に適応したフルスクリーンを実現します

独自のデモを作成するときに、display:flex を使用して垂直方向の中央揃えを実現したいと思い...

Linuxプロセス監視と自動再起動の簡単な実装方法

目的: Linux では、さまざまな理由でサーバー プログラムがダンプされ、ユーザーの使用に影響する...

HTMLタグの説明

HTMLタグの説明1. HTMLタグタグ: !DOCTYPE説明: HTML ドキュメントが準拠する...

ネイティブ js はカスタム スクロール バー コンポーネントを実装します

この記事の例では、カスタムスクロールバーコンポーネントを実装するためのjsの具体的なコードを参考まで...

一般的な nginx コマンドをシェル スクリプトに組み込む方法の詳細な説明

1. nginxシェルスクリプトを保存するフォルダを作成する /usr/local/タスク/ngin...

過去の Linux イメージの問題を修正するためのサンプル分析

過去の Linux イメージに関する問題を修正従来の Linux イメージで作成された ECS クラ...

CSSをインポートする方法に関する詳細な洞察の要約

CSS の開発履歴についてはここでは紹介しません。ブログを書いている理由の 1 つは、フロントエンド...

Linux ソースコードからのソケット (TCP) バインドの詳細な説明

目次1. 最も単純なサーバー側の例2. バインドシステムコール2.1、inet_bind 2.2、i...

ウェブサイトのユーザビリティとコンバージョン率を向上させる 25 のツール

ウェブサイトの場合、ユーザビリティとは、ユーザーが必要な情報を効果的に見つけたり、タスクを完了したり...