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

推薦する

Linux で MySQL データベースのスケジュールされたバックアップを実装する簡単な方法

詳細な手順は次のとおりです。 1. ディスク容量を確認します。 [root@localhost バッ...

HttpsページでBaiduシェアを使用するためのソリューション

サイト全体で https アクセスを有効にしてから、共有コードが利用できなくなり、有効になっていた小...

CSS3で実装された読み込みアニメーション

成果を達成する実装コード <h1>123WORDPRESS.COM</h1>...

UbuntuにMySQLをインストールするときにデフォルトのパスワードを変更する詳細な手順

ステップ1: ディレクトリに入ります: cd /etc/mysql、debian.cnfファイルを表...

MySQL列挙型のテスト例

プロジェクトを開発しているとき、支払い済み、支払済み、クローズ済み、返金済みなどの注文ステータスなど...

VUE+Canvasはデスクトップピンボールブロック破壊ゲームのサンプルコードを実装します

誰もがピンボールやレンガ崩しのゲームをプレイしたことがあるでしょう。左と右のキーを使用して、下にある...

Keras を使って SQL インジェクション攻撃を判断する (例の説明)

この記事では、ディープラーニングフレームワーク keras を使用して、SQL インジェクションの特...

Linux ファイルシステムの説明: ext4 以降

今日は、ext3 や他の以前のファイル システムとの違いを含め、ext4 の歴史について説明します。...

Vue が DingTalk の出勤カレンダーを実装

この記事では、DingTalkの勤怠カレンダーを実装するためのVueの具体的なコードを参考までに共有...

Bootstrap3.0 学習ノートテーブル関連

この記事では、Webサイトを作ったことがある人にとっては馴染みのあるテーブルについて主に説明します。...

CSS3は、変換変形とイベントを組み合わせて扇形のナビゲーションを完成させます。

この場合、transition という単語を間違って書いたため、午後中ずっとそれに取り組みました。本...

mysql の not equal to null と equal to null の書き方の詳細説明

1. テーブル構造 2. 表データ 3. クエリのteacher_nameフィールドは空にすることは...

Windows プラットフォーム構成 5.7 バージョン + MySQL データベース サービス

ルートユーザーのパスワードを初期化するプロセスと、よくある2つの問題の解決策が含まれています。 1....

フロントエンド開発一般マニュアル(ツール、Webサイト、経験などを含む)

今日は何もすることがなかったので、いくつかのツール(オンラインとクライアント)、よく使用する URL...

よく使われるシングルページアプリケーションウェブサイト共有

CSS3お願いしますこのウェブサイトを自分で見て、パラメータを変更し、CSS3効果をオン/オフにする...