Antworten:
Das exists
Schlüsselwort kann auf diese Weise verwendet werden, aber es ist wirklich 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 am nützlichsten, wenn Sie if
bedingte Anweisungen haben, da exists
dies viel schneller sein kann als count
.
Das in
wird am besten verwendet, wenn Sie eine statische Liste übergeben müssen:
select * from [table]
where [field] in (1, 2, 3)
Wenn Sie eine Tabelle in einer in
Anweisung haben, ist es sinnvoller, eine zu verwenden join
, aber meistens sollte es keine Rolle spielen. Der Abfrageoptimierer sollte in beiden Fällen denselben Plan zurückgeben. In einigen Implementierungen (meistens älter, wie z. B. Microsoft SQL Server 2000) erhalten in
Abfragen immer einen verschachtelten Join- Plan, während join
Abfragen je nach Bedarf verschachtelt, zusammengeführt oder hashen . Modernere Implementierungen sind intelligenter und können den Plan auch bei in
Verwendung anpassen .
select * from [table] where [field] in (select [field] from [table2])
Gibt die gleichen Ergebnisse (und Abfragepläne) wie zurück select * from [table] join [table2] on [table2].[field] = [table].[field]
.
table
, während die zweite alles von table
und zurückgibt table2
. In einigen (meist älteren) SQL-Datenbanken wird die in
Abfrage als verschachtelter Join implementiert, während die join
Abfrage verschachtelt, zusammengeführt, gehasht usw. werden kann - was auch immer am schnellsten ist.
exists
kann innerhalb einer case-Anweisung verwendet werden, so dass sie auch auf diese Weise nützlich sein können, dhselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTS
Hier erfahren Sie, ob eine Abfrage Ergebnisse zurückgegeben 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 Literalwerte wie diesen verwenden:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
Sie können Abfrageergebnisse auch mit der folgenden IN
Klausel verwenden:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Basierend auf dem 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 dem Kostenoptimierer :
Ich gehe davon aus, dass Sie wissen, was sie tun, und daher anders verwendet werden. Daher verstehe ich Ihre Frage wie folgt: Wann wäre es eine gute Idee, das SQL neu zu schreiben, um IN anstelle von EXISTS zu verwenden, oder umgekehrt.
Ist das eine faire Annahme?
Bearbeiten : Der Grund, den ich frage, ist, dass Sie in vielen Fällen eine auf IN basierende SQL neu schreiben können, um stattdessen EXISTS zu verwenden, und umgekehrt. Bei einigen Datenbank-Engines behandelt das Abfrageoptimierungsprogramm 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 einem Join:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Meine Frage bleibt also weiterhin: Ist das Originalplakat eine Frage, was IN und EXISTS tun und wie man es verwendet, oder ob er eine SQL mit IN neu schreibt, um stattdessen EXISTS zu verwenden, oder umgekehrt, eine gute Idee ist?
JOIN
benötigen Sie eineDISTINCT
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.
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'
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 t1
Ihre ID den Wert Null hat, werden sie von Abfrage 1 gefunden, aber Abfrage 2 kann keine Nullparameter finden.
Ich meine, ich IN
kann nichts mit null vergleichen, also hat es kein Ergebnis für null, aber ich kann alles mit null EXISTS
vergleichen.
Wenn Sie den IN
Operator verwenden, scannt die SQL-Engine alle Datensätze, die aus der inneren Abfrage abgerufen wurden. Wenn wir dagegen verwenden EXISTS
, stoppt die SQL-Engine den Scanvorgang, sobald eine Übereinstimmung gefunden wurde.
IN unterstützt nur Gleichheitsrelationen (oder Ungleichheit, wenn NICHT vorangestellt ist ).
Es ist ein Synonym für = any / = some , z
select *
from t1
where x in (select x from t2)
;
EXISTS unterstützt verschiedene Arten von Beziehungen, die nicht mit IN ausgedrückt werden können , z.
select *
from t1
where exists (select null
from t2
where t2.x=t1.x
and t2.y>t1.y
and t2.z like '℅' || t1.z || '℅'
)
;
Die angeblichen Leistungs- und technischen Unterschiede zwischen EXISTS und IN können auf Implementierungen / Einschränkungen / Fehler bestimmter Anbieter zurückzuführen sein. Oft handelt es sich jedoch nur um Mythen, die aufgrund mangelnden Verständnisses der internen Datenbanken entstanden sind.
Die Definition der Tabellen, die Genauigkeit der Statistiken, die Datenbankkonfiguration und die Version des Optimierers wirken sich alle auf den Ausführungsplan und damit auf die Leistungsmetriken aus.
Das Exists
Schlüsselwort wertet wahr oder falsch aus, aber das IN
Schlüsselwort vergleicht alle Werte in der entsprechenden Unterabfragespalte. Ein anderer Select 1
kann mit Exists
Befehl verwendet werden. Beispiel:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Ist IN
aber weniger effizient so Exists
schneller.
Ich glaube,
EXISTS
In diesem Fall müssen Sie die Ergebnisse der Abfrage mit einer anderen Unterabfrage abgleichen. Die Ergebnisse der Abfrage Nr. 1 müssen abgerufen werden, wenn die SubQuery-Ergebnisse übereinstimmen. Art eines Joins. Wählen Sie beispielsweise die Kundentabelle Nr. 1 aus, die auch die Bestelltabelle Nr. 2 aufgegeben hat
IN soll abrufen, ob der Wert einer bestimmten Spalte in IN
einer Liste liegt (1,2,3,4,5). ZB Kunden auswählen, die in den folgenden Postleitzahlen liegen, dh Postleitzahlwerte liegen in der Liste (....).
Wann man es übereinander verwendet ... wenn man das Gefühl hat, dass es angemessen liest (kommuniziert Absicht besser).
Der Unterschied liegt hier:
select *
from abcTable
where exists (select null)
Die obige Abfrage gibt alle Datensätze zurück, während die untere Abfrage leer zurückgibt.
select *
from abcTable
where abcTable_ID in (select null)
Probieren Sie es aus und beobachten Sie die Ausgabe.
Welche schneller ist, hängt von der Anzahl der von der inneren Abfrage abgerufenen Abfragen ab:
EXIST bewertet auf wahr oder falsch, aber IN vergleicht mehrere Werte. Wenn Sie nicht wissen, dass der Datensatz vorhanden ist oder nicht, sollten Sie EXIST wählen
Der Grund dafür ist, dass der EXISTS-Operator nach dem Prinzip „zumindest gefunden“ arbeitet. Es gibt true zurück und stoppt das Scannen der Tabelle, sobald mindestens eine übereinstimmende Zeile gefunden wurde.
Wenn andererseits der IN-Operator mit einer Unterabfrage kombiniert wird, muss MySQL zuerst die Unterabfrage verarbeiten und dann das Ergebnis der Unterabfrage verwenden, um die gesamte Abfrage zu verarbeiten.
Als Faustregel gilt, dass der EXISTS-Operator eine bessere Leistung bietet, wenn die Unterabfrage ein großes Datenvolumen enthält.
Die Abfrage, die den IN-Operator verwendet, wird jedoch schneller ausgeführt, wenn die von der Unterabfrage zurückgegebene Ergebnismenge sehr klein ist.
Meines Wissens nach sollten beide gleich sein, solange es sich nicht um NULL-Werte handelt.
Der gleiche Grund, warum die Abfrage den Wert für = NULL vs nicht zurückgibt, ist NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
Was das Argument Boolean vs Comparator betrifft, müssen zum Generieren eines Boolean beide Werte verglichen werden, und so funktioniert jede Bedingung, wenn sie funktioniert. Daher verstehe ich nicht, wie sich IN und EXISTS unterschiedlich verhalten.
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
Wenn eine Unterabfrage mehr als einen Wert zurückgibt, müssen Sie möglicherweise die äußere Abfrage ausführen, wenn die Werte in der in der Bedingung angegebenen Spalte mit einem Wert in der Ergebnismenge der Unterabfrage übereinstimmen. Um diese Aufgabe auszuführen, müssen Sie das in
Schlüsselwort verwenden.
Sie können eine Unterabfrage verwenden, um zu überprüfen, ob eine Reihe von Datensätzen vorhanden ist. Dazu müssen Sie die exists
Klausel mit einer Unterabfrage verwenden. Das exists
Schlüsselwort gibt immer den Wert true oder false zurück.
Ich glaube, das hat eine einfache Antwort. Warum überprüfen Sie es nicht von den Leuten, die diese Funktion in ihren Systemen entwickelt haben?
Wenn Sie ein MS SQL-Entwickler sind, finden Sie hier die Antwort direkt von Microsoft.
IN
::
Legt fest, ob ein angegebener Wert mit einem Wert in einer Unterabfrage oder einer Liste übereinstimmt.
EXISTS
::
Gibt eine Unterabfrage an, die auf das Vorhandensein von Zeilen getestet werden soll.
Ich habe festgestellt, dass die Verwendung des EXISTS-Schlüsselworts oft sehr langsam ist (das ist in Microsoft Access sehr richtig). Ich verwende stattdessen den Join-Operator auf folgende Weise: Sollte-ich-das-Schlüsselwort-verwenden-existiert-in-SQL
EXISTS ist schneller in der Leistung als IN. Wenn sich die meisten Filterkriterien in einer Unterabfrage befinden, ist es besser, IN zu verwenden. Wenn sich die meisten Filterkriterien in der Hauptabfrage befinden, ist es besser, EXISTS zu verwenden.
Wenn Sie den IN-Operator verwenden, scannt die SQL-Engine alle Datensätze, die aus der inneren Abfrage abgerufen wurden. Wenn wir dagegen EXISTS verwenden, stoppt die SQL-Engine den Scanvorgang, sobald eine Übereinstimmung gefunden wurde.
IN
und EXISTS
kann äquivalent und ineinander transformiert sein.
JOIN
als Ersatz verwenden könnenIN
.