513 Stimmen

Unterschied zwischen EXISTS und IN in SQL?

Was ist der Unterschied zwischen dem EXISTS y IN Klausel in SQL?

Wann sollten wir die EXISTS und wann sollten wir die IN ?

258voto

Keith Punkte 141163

En exists Schlüsselwort kann auf diese Weise verwendet werden, aber eigentlich ist es dazu gedacht, das Zählen zu vermeiden:

--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 ... )

Dies ist besonders nützlich, wenn Sie if bedingte Anweisungen, wie exists kann viel schneller sein als count .

En in wird am besten verwendet, wenn Sie eine statische Liste zu übergeben haben:

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

Wenn Sie eine Tabelle in einer in Anweisung ist es sinnvoller, eine join aber meistens sollte es keine Rolle spielen. Der Abfrageoptimierer sollte in beiden Fällen denselben Plan zurückgeben. In einigen Implementierungen (meist älteren, wie Microsoft SQL Server 2000) in Abfragen erhalten immer eine geschachtelte Verbindung Plan, während join Abfragen werden verschachtelt verwendet, zusammenführen o Hash nach Bedarf. Modernere Implementierungen sind intelligenter und können den Plan auch dann anpassen, wenn in verwendet wird.

159voto

Matt Hamilton Punkte 193704

EXISTS zeigt an, ob eine Abfrage zu einem Ergebnis geführt hat, z.B.:

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

IN wird verwendet, um einen Wert mit mehreren zu vergleichen, und kann literale Werte verwenden, wie hier:

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

Sie können die Abfrageergebnisse auch mit der Funktion IN Klausel, etwa so:

SELECT * 
FROM Orders 
WHERE ProductNumber IN (
    SELECT ProductNumber 
    FROM Products 
    WHERE ProductInventoryQuantity > 0)

93voto

jackson Punkte 931

Basierend auf Regeloptimierer :

  • EXISTS ist viel schneller als IN wenn die Ergebnisse der Unterabfrage sehr groß sind.
  • IN ist schneller als EXISTS wenn die Ergebnisse der Unterabfrage sehr klein sind.

Basierend auf Kostenoptimierer :

  • Es gibt keinen Unterschied.

47voto

Lasse V. Karlsen Punkte 364542

Ich gehe davon aus, dass Sie wissen, was sie tun, und daher werden sie unterschiedlich verwendet, also verstehe ich Ihre Frage so: Wann wäre es eine gute Idee, das SQL umzuschreiben, um IN statt EXISTS zu verwenden, oder umgekehrt.

Ist das eine berechtigte Annahme?


bearbeiten : Der Grund für meine Frage ist, dass man in vielen Fällen ein auf IN basierendes SQL umschreiben kann, um stattdessen ein EXISTS zu verwenden, und umgekehrt, und bei einigen Datenbank-Engines behandelt der Abfrageoptimierer die beiden unterschiedlich.

Zum Beispiel:

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

kann umgeschrieben werden in:

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

oder mit einer Verbindung:

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

Also meine Frage steht immer noch, ist der ursprüngliche Poster fragen, was IN und EXISTS tut, und somit, wie es zu verwenden, oder fragt er, ob das Umschreiben eines SQL mit IN zu EXISTS stattdessen verwenden, oder umgekehrt, eine gute Idee sein wird?

33voto

Alireza Masali Punkte 658
  1. EXISTS ist viel schneller als IN wenn das Ergebnis der Unterabfrage sehr groß ist.
    IN ist schneller als EXISTS wenn die Ergebnisse der Unterabfrage sehr klein sind.

    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. Abfrage 1

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

    Abfrage 2

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

    Wenn in t1 Ihre Kennung hat einen Nullwert, dann wird Abfrage 1 sie finden, aber Abfrage 2 kann keine Nullparameter finden.

    Ich meine IN kann nichts mit null vergleichen, hat also kein Ergebnis für null, aber EXISTS kann alles mit Null vergleichen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X