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 でサードパーティのコンポーネントライブラリをオンデマンドでロードする方法

推薦する

SQL でテーブルにフィールドとコメントを追加する方法

1. フィールドを追加します。 alter table テーブル名 ADD フィールド名 タイプ;例...

Facebook によるインターネット サービスのほぼ完璧な再設計

<br />出典: http://www.a-xuan.cn/?p=197 先ほどFac...

CSSの固定位置属性の詳細な説明

モバイル アプリを開発する場合、Web サイトが特定の高さまでスクロールしたときにコンテンツの一部を...

VueのSSRサーバーサイドレンダリング例の詳細な説明

サーバーサイドレンダリング (SSR) を使用する理由検索エンジンのクローラーが完全にレンダリングさ...

CSS アニメーション プロパティの使用方法とサンプル コード (transition/transform/animation)

開発中、優れたユーザー インターフェイスには常にいくつかのアニメーションが組み込まれます。 CSS ...

CentOS に PHP5 をインストール、PHP をアンインストール、PHP7 をインストールするチュートリアル

まず、PHP5をインストールするのはとても簡単ですyum install php PHP5 を使用し...

Linux (Ubuntu 18.04) に vim エディタをインストールする方法

デスクトップ システムをダウンロードするには、Ubuntu の公式 Web サイト (https:/...

MYSQLストアドプロシージャコメントの詳細な説明

目次1. 使用方法2. 準備3. 文法3.1 変数と代入3.2 入力および出力パラメータ3.3 プロ...

Podmanはコンテナを自動的に起動し、Dockerと比較します

目次1. podmanの紹介2. Dockerと比較した利点3. 互換性4. バックグラウンド サー...

Vue で動的に読み込まれたローカル画像を処理する方法

問題を見つける今日は、vue ファイルにローカル画像を導入する際に問題が発生したので、この記事を書き...

入力スクリプトなしでタイプ拡張を使用する方法

序文JS の型付けが弱く、記述基準が緩く、開発ツールのサポートが弱いため、前任者のコードをメンテナン...

MySQLの文字タイプは大文字と小文字を区別します

デフォルトでは、MySQLの文字タイプは大文字と小文字を区別しません。つまり、name='A...

Tomcat 7.0 で仮想ディレクトリを設定し、仮想パスを構成する方法

Tomcat7.0は仮想ディレクトリを設定します(1)現在、当社のウェブサイトはデフォルトのディレク...

vue3 コンポーネント通信方法の概要と例

vue3コンポーネントの通信モードは次のとおりです。小道具$放出$expose / 参照$属性vモデ...

MySQL で複数の主キーが定義されているエラーの解決方法

主キーを作成するには 2 つの方法があります。 テーブルテーブル名を作成( フィールド名タイプ、 フ...