MySQL における in と exists の使い方と違いの紹介

MySQL における in と exists の使い方と違いの紹介

まずコードを書いて

(int i=0;i<1000;i++){
 (int j=0;j<5;j++){
 System.out.println("hello");
 }
}

 (int i=0;i<5;i++){
 (int j=0;j<1000;j++){
 System.out.println("hello");
 }
}

上記のコードを分析すると、ループの順序を除いて 2 行のコードに違いがないことがわかります。実際の実行では、2 行で消費される時間とスペースも同じになるはずです。しかし、これは Java に限った話です。では、シナリオを変えてみましょう。最も外側のループはデータベースへの接続操作で、内側のループは検索操作です。これで、2 つの操作の結果は大きく異なります。

その理由は、データベースの特性によって決まります。データベース内のクエリ操作と比較すると、接続を確立するにはより多くのリソースが消費されます。最初のコードでは 1,000 の接続が確立されましたが、各接続では 5 つのクエリしか実行されなかったため、明らかに無駄でした。

したがって、データベースを操作するときに従う必要がある操作は、小さなテーブルが大きなテーブルを操作する(小さなデータセットが大きなデータセットを操作する)ことです。

存在し、

テーブル構造

tbl_emp は従業員テーブルであり、deptld は部門 ID です。 tbl_dept は部門テーブルです。従業員テーブルにはゲストが含まれており、そのdeptldフィールドは-1です。

mysql> desc tbl_emp;
+--------+-------------+------+-----+---------+----------------+
| フィールド | タイプ | Null | キー | デフォルト | 追加 |
+--------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | 自動増分 |
| 名前 | varchar(20) | はい | | NULL | |
| deptld | int(11) | はい | MUL | NULL | |
+--------+-------------+------+-----+---------+----------------+
セット内の 3 行 (0.00 秒)

mysql> desc tbl_dept;
+----------+-------------+------+-----+---------+----------------+
| フィールド | タイプ | Null | キー | デフォルト | 追加 |
+----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | 自動増分 |
| deptName | varchar(30) | YES | MUL | NULL | |
| locAdd | varchar(40) | はい | | NULL | |
+----------+-------------+------+-----+---------+----------------+
セット内の 3 行 (0.01 秒)

会社には部門よりも多くの従業員がいることは周知の事実です。今、私たちは次のような要件を持っています:この会社に属する従業員(訪問客を除く)を照会するには、次のコードを使用して解決できます。

使用場所

# まず、部門テーブル内のすべての ID をクエリし、次に従業員テーブルの deptld フィールドと比較します。見つかった場合は、それを保持します。

mysql> select * from tbl_emp a where a.deptld in (select id from tbl_dept);

in キーワードは or の連結のようなものです。たとえば、上記の SQL のサブクエリによって見つかった結果は 1、2、3 です。 SQL文は次の形式と同等です。

mysql> select * from tbl_emp a where a.deptld=1 or a.deptld=2 or a.deptld=3

一般的に、in キーワードはサブクエリのすべての結果を検索します。結果セットが B で、合計 m レコードがあると仮定します。次に、サブクエリ条件の結果セットは m 個の部分に分解され、m 個のクエリが実行されます。ここでは A のインデックスが主に使用されており、B テーブルはクエリにほとんど影響を与えていないことがわかります。

存在する使用

mysql> tbl_emp a から * を選択します (tbl_dept b から 1 を選択します (a.deptld = b.id))。

終了: 条件検証のためにメインクエリのデータをサブクエリに入れ、検証結果 (True または False) に基づいてメインクエリのレコードを保持するかどうかを決定します。

for (i = 0; i < count(A); i++) { // レコードの合計数を走査します Aa = get_record(A, i); // テーブルからレコードを 1 つずつ取得します Aif (B.id = a[id]) // サブ条件が metsult[] = a の場合;
}
結果を返します。

主にテーブル B のインデックスが使用されており、テーブル A のインデックスはクエリの効率にほとんど影響を与えないことがわかります。

結論は

mysql> select * from tbl_emp a where a.deptld in (select id from tbl_dept);

tbl_deptのレコード数がtbl_empのレコード数より少ない場合は、

mysql> tbl_emp a から * を選択します (tbl_dept b から 1 を選択します (a.deptld = b.id))。

tbl_deptのレコード数がtbl_empのレコード数を超える場合は、

INとEXISTSの違いについてご紹介します

1. INクエリ分析

SELECT * FROM A WHERE id IN (SELECT id FROM B);

同等: 1. SELECT id FROM B -----> 最初にクエリを実行します

2. SELECT * FROM A WHERE A.id = B.id

上記の in() のクエリは 1 回だけ実行されます。B のすべての ID をクエリしてキャッシュします。次に、テーブル A でクエリされた ID がキャッシュに存在するかどうかを確認します。存在する場合は、テーブル A のすべての結果セットがトラバースされるまで、A のクエリ データが結果セットに追加されます。

以下は、結果セットを走査してINクエリを分析したものだ。

上記のプログラムから、テーブル B のデータが大きい場合、テーブル B のすべてのデータを一度に走査するため、in() クエリの使用は適切ではないことがわかります。

例えば:

1. テーブル A には 100 件のレコードがあり、テーブル B には 1000 件のレコードがあるため、最大で 100*1000 回までしか走査できず、非常に非効率的です。

2. テーブル A に 1000 件のレコードがあり、テーブル B に 100 件のレコードがある場合、最大 1000 * 100 件のレコードを走査でき、内部ループの数が削減され、効率が大幅に向上します。

結論: IN() クエリは、テーブル B のデータがテーブル A のデータよりも小さい場合に適しています。IN() クエリはキャッシュからデータを取得します。

2. EXISTSクエリ分析

構文: SELECT field FROM table WHERE EXISTS (サブクエリ);

SELECT * FROM a WHERE EXISTS(SELECT 1 FROM b WHERE B.id = A.id);

上記のクエリは次のクエリと同等です。

A から * を選択します。
B から I を選択する (B.id = A.id);

EXISTS() クエリは SELECT * FROM A クエリを実行し、A.length 回実行し、EXISTS() クエリの結果をキャッシュしません。これは、EXISTS() クエリが true または false のブール値を返すためです。これは、EXISTS() クエリにレコードがあるかどうかのみを考慮し、特定の結果セットとは関係ありません。

EXISTS() クエリは、メイン クエリの結果セットを検証のためにサブクエリに配置し、検証結果が true か false かに基づいてメイン クエリのデータ結果を保存するかどうかを決定します。

要約する

以上は、MySQL における in と exists の使い方と違いの紹介です。お役に立てれば幸いです。ご質問があれば、メッセージを残していただければ、すぐに返信いたします。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。

以下もご興味があるかもしれません:
  • MySQL における EXISTS と IN の使用法の比較
  • MySQL における exists、in、any の基本的な使い方
  • MySQL ステートメントにおける IN と Exists の比較分析
  • MySQLの存在と詳細な説明と違い
  • MySQL の in クエリと exists クエリの違いの概要
  • MYSQL IN と EXISTS の最適化の例
  • mysql は、含まれていない、左結合、IS NULL、NOT EXISTS の効率の問題のレコードです
  • MySQL における in と exists の違いの詳細な説明

<<:  LDAP ユーザー認証を使用するように Linux を構成する方法

>>:  Vue3 でサードパーティのコンポーネントライブラリをオンデマンドでロードする方法

推薦する

均一なアニメーション効果を実現するJavaScript

この記事の例では、JavaScriptで等速アニメーションを実装するための具体的なコードを参考までに...

入力ボックスの値を取得する方法のReactの例

入力ボックスの値を取得する複数の方法最初の方法は、制御されていないコンポーネントの取得です2番目の方...

MySQLのExcelへのエクスポート方法の分析

この記事では、MySQL を使用してデータを Excel にエクスポートする方法について説明します。...

Vueプロジェクトでvuexを使用する方法

目次Vuex とは何ですか? Vuex 使用サイクル図私のストアディレクトリvuexの例の実装要約す...

MySQLクエリが遅い理由

目次1. 遅いところはどこですか? 2. 不要なデータをクエリしましたか? 1. 不要なレコードをク...

HTMLファイルとは何ですか?HTMLファイルを開く方法

HTML は Hypertext Markup Language の略です。現在、ほとんどの Web...

Docker 実行時にユーザーとグループを管理する方法

Docker はプロセスを中核としてシステムリソースを分離する管理ツールです。分離は、オペレーティン...

MySQL でデータ テーブルを作成し、主キーと外部キーの関係を確立する方法の詳細な説明

序文MySQL テーブルの主キーと外部キーを作成するときは、次の点に注意する必要があります。主キーと...

MySQLでスケジュールされたタスクを設定する方法の分析

この記事では、例を使用して、MySQL でスケジュールされたタスクを設定する方法について説明します。...

Python MySQL データベース テーブルの変更とクエリ

Python は MySQL に接続してデータベース テーブルを変更およびクエリします。 pytho...

Echarts バー水平棒グラフのサンプルコード

目次横棒グラフデータとスタイルを動的に更新するeChartsの幅と高さの適応の問題を解決する縦棒グラ...

WebプロジェクトのDockerデプロイメントの実装

前回の記事では、docker サービスをインストールしました。引き続き、Web プロジェクトのデプロ...

MySQLレジストリをクリアする方法

具体的な方法: 1. [ win+r ] を押して実行ウィンドウを開き、「regedit」と入力して...

MySQLにおける分散ロックの考え方をDBの助けを借りて詳しく説明します

序文スタンドアロン ロックであっても分散ロックであっても、共有データに基づいて現在の操作の動作を判断...

Dockerfileを使用してDockerイメージを構築する

目次Dockerfileを使用してDockerイメージを構築する1. Dockerfile とは何で...