481

EXISTSSQLのandIN句の違いは何ですか?

いつ使用する必要がEXISTSあり、いつ使用する必要がありますINか?

4

21 に答える 21

239

キーワードはそのexistsように使用できますが、実際には、カウントを回避する方法として意図されています。

--this statement needs to check the entire table
select count(*) from [table] where ...

--this statement is true as soon as one match is found
exists ( select * from [table] where ... )

ifこれは、条件付きステートメントがある場合に最も役立ちます。これはexists、よりもはるかに高速である可能性があるためcountです。

in渡す静的リストがある場合に最適です。

 select * from [table]
 where [field] in (1, 2, 3)

ステートメントにテーブルがある場合は、inを使用する方が理にかなっていますがjoin、ほとんどの場合、それは問題ではありません。クエリオプティマイザーは、どちらの方法でも同じプランを返す必要があります。一部の実装(Microsoft SQL Server 2000など、ほとんどの場合古い)では、inクエリは常にネストされた結合プランを取得しますが、joinクエリは必要に応じてネスト、マージ、またはハッシュを使用します。最新の実装はよりスマートで、in使用されている場合でも計画を調整できます。

于 2008-08-24T09:37:52.493 に答える
146

EXISTSクエリが結果を返したかどうかを教えてくれます。例えば:

SELECT * 
FROM Orders o 
WHERE EXISTS (
    SELECT * 
    FROM Products p 
    WHERE p.ProductNumber = o.ProductNumber)

IN1つの値を複数の値と比較するために使用され、次のようにリテラル値を使用できます。

SELECT * 
FROM Orders 
WHERE ProductNumber IN (1, 10, 100)

IN次のように、句でクエリ結果を使用することもできます。

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)
于 2008-08-24T08:47:45.967 に答える
88

ルールオプティマイザに基づく:

  • EXISTSINサブクエリの結果が非常に大きい場合は、よりもはるかに高速です。
  • INEXISTSサブクエリの結果が非常に小さい場合は、よりも高速です。

コストオプティマイザーに基づく:

  • 違いはありません。
于 2010-10-19T01:35:32.520 に答える
45

私はあなたがそれらが何をするかを知っていると仮定しているので、私はあなたの質問を次のように理解するつもりです:EXISTSの代わりにINを使用するようにSQLを書き直すのはいつですか?

それは公正な仮定ですか?


編集:私が尋ねている理由は、多くの場合、代わりにEXISTSを使用するようにINに基づいてSQLを書き直すことができ、その逆も可能であり、一部のデータベースエンジンでは、クエリオプティマイザが2つを異なる方法で処理するためです。

例えば:

SELECT *
FROM Customers
WHERE EXISTS (
    SELECT *
    FROM Orders
    WHERE Orders.CustomerID = Customers.ID
)

次のように書き換えることができます。

SELECT *
FROM Customers
WHERE ID IN (
    SELECT CustomerID
    FROM Orders
)

または参加して:

SELECT Customers.*
FROM Customers
    INNER JOIN Orders ON Customers.ID = Orders.CustomerID

それで、私の質問はまだ残っています、元のポスターはINとEXISTSが何をするのか、したがってそれをどのように使用するのか疑問に思っていますか、それとも代わりにEXISTSを使用するようにINを使用してSQLを書き直すか、またはその逆かを尋ねますか?

于 2008-08-24T08:45:39.717 に答える
31
  1. EXISTSINサブクエリの結果が非常に大きい場合よりもはるかに高速です。サブクエリの結果が非常に小さい場合
    INよりも高速です。EXISTS

    CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
    GO
    CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
    GO
    
    INSERT INTO t1
    SELECT 1, 'title 1', 5 UNION ALL
    SELECT 2, 'title 2', 5 UNION ALL
    SELECT 3, 'title 3', 5 UNION ALL
    SELECT 4, 'title 4', 5 UNION ALL
    SELECT null, 'title 5', 5 UNION ALL
    SELECT null, 'title 6', 5
    
    INSERT INTO t2
    SELECT 1, 1, 'data 1' UNION ALL
    SELECT 2, 1, 'data 2' UNION ALL
    SELECT 3, 2, 'data 3' UNION ALL
    SELECT 4, 3, 'data 4' UNION ALL
    SELECT 5, 3, 'data 5' UNION ALL
    SELECT 6, 3, 'data 6' UNION ALL
    SELECT 7, 4, 'data 7' UNION ALL
    SELECT 8, null, 'data 8' UNION ALL
    SELECT 9, 6, 'data 9' UNION ALL
    SELECT 10, 6, 'data 10' UNION ALL
    SELECT 11, 8, 'data 11'
    
  2. クエリ 1

    SELECT
    FROM    t1 
    WHERE   not  EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
    

    クエリ 2

    SELECT t1.* 
    FROM   t1 
    WHERE  t1.id not in (SELECT  t2.t1id FROM t2 )
    

    ID に null 値がある場合t1、クエリ 1 はそれらを見つけますが、クエリ 2 は null パラメータを見つけることができません。

    つまりIN、何もnullと比較できないため、nullの結果はありませんが、EXISTSすべてをnullと比較できます。

于 2012-07-04T12:40:45.590 に答える
18

演算子を使用している場合IN、SQL エンジンは内部クエリからフェッチされたすべてのレコードをスキャンします。一方、 を使用している場合EXISTS、SQL エンジンは一致が見つかるとすぐにスキャン プロセスを停止します。

于 2013-07-16T08:00:48.980 に答える
10

Existsキーワードは true または false を評価しますが、キーワードINは対応するサブクエリ列のすべての値を比較します。もう 1 つはコマンドSelect 1で使用できますExists。例:

SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)

しかし、IN効率が悪いのでExists高速です。

于 2012-05-25T05:00:44.210 に答える
5

おもう、

  • EXISTSクエリの結果を別のサブクエリと照合する必要がある場合です。クエリ#1の結果は、サブクエリの結果が一致する場所で取得する必要があります。結合の種類..たとえば、注文テーブル#2も行った顧客テーブル#1を選択します

  • INは、特定の列の値がINリスト(1,2,3,4,5)にあるかどうかを取得します。たとえば、次の郵便番号にある顧客を選択します。つまり、zip_code値は(....)リストにあります。

どちらか一方を使用する場合...適切に読み取れると感じた場合(意図をより適切に伝達します)。

于 2008-08-24T08:50:31.497 に答える
3

その理由は、EXISTS 演算子が「少なくとも見つかった」原則に基づいて機能するためです。true を返し、少なくとも 1 つの一致する行が見つかると、テーブルのスキャンを停止します。

一方、IN 演算子をサブクエリと組み合わせると、MySQL は最初にサブクエリを処理し、次にサブクエリの結果を使用してクエリ全体を処理する必要があります。

一般的な経験則では、サブクエリに大量のデータが含まれる場合、EXISTS 演算子の方がパフォーマンスが向上します。

ただし、サブクエリから返される結果セットが非常に小さい場合は、IN 演算子を使用するクエリの方が高速に実行されます。

于 2016-04-07T09:04:10.500 に答える
3

違いはここにあります:

select * 
from abcTable
where exists (select null)

上記のクエリはすべてのレコードを返しますが、下のクエリは空を返します。

select *
from abcTable
where abcTable_ID in (select null)

試してみて、出力を観察してください。

于 2015-05-19T12:42:56.670 に答える
3

私の知る限り、サブクエリがNULL値を返すと、ステートメント全体が になりNULLます。その場合、EXITSキーワードを使用しています。サブクエリで特定の値を比較したい場合は、INキーワードを使用しています。

于 2012-03-21T02:01:15.587 に答える
2

In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.

https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403

于 2017-08-17T14:10:53.087 に答える
0

サブクエリが複数の値を返す場合、条件で指定された列内の値がサブクエリの結果セットのいずれかの値と一致する場合、外側のクエリを実行する必要がある場合があります。このタスクを実行するには、inキーワードを使用する必要があります。

サブクエリを使用して、一連のレコードが存在するかどうかを確認できます。このためにはexists、サブクエリで句を使用する必要があります。キーワードはexists常に true または false の値を返します。

于 2012-12-04T11:24:04.720 に答える
-1

EXISTS は IN よりもパフォーマンスが高速です。ほとんどのフィルター基準がサブクエリにある場合は IN を使用することをお勧めします。ほとんどのフィルター基準がメイン クエリにある場合は、EXISTS を使用することをお勧めします。

于 2013-04-09T19:03:43.103 に答える
-2

IN 演算子を使用している場合、SQL エンジンは内部クエリからフェッチされたすべてのレコードをスキャンします。一方、EXISTS を使用している場合、SQL エンジンは一致が見つかるとすぐにスキャン プロセスを停止します。

于 2012-06-04T01:43:38.290 に答える