Risposte:
La exists
parola chiave può essere utilizzata in questo modo, ma in realtà è intesa come un modo per evitare il conteggio:
--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 ... )
Questo è molto utile laddove hai if
dichiarazioni condizionali, poiché exists
può essere molto più veloce di count
.
Il in
è utilizzato al meglio in cui si dispone di un elenco statico di passare:
select * from [table]
where [field] in (1, 2, 3)
Quando hai una tabella in in
un'istruzione ha più senso usare un join
, ma soprattutto non dovrebbe importare. Query Optimizer dovrebbe restituire lo stesso piano in entrambi i modi. In alcune implementazioni (per lo più precedenti, come Microsoft SQL Server 2000) le in
query riceveranno sempre un piano di join nidificato , mentre le join
query utilizzeranno nidificato, unisci o hash come appropriato. Le implementazioni più moderne sono più intelligenti e possono adattare il piano anche quando in
viene utilizzato.
select * from [table] where [field] in (select [field] from [table2])
restituisce gli stessi risultati (e piano di query) di select * from [table] join [table2] on [table2].[field] = [table].[field]
.
table
, mentre la seconda restituisce tutto da table
e table2
. In alcuni database SQL (per lo più vecchi) la in
query verrà implementata come join nidificato, mentre la join
query può essere nidificata, unita, hash, ecc., Qualunque sia la più rapida.
exists
può essere utilizzato all'interno di un'istruzione case, quindi possono essere utili in questo modo anche ad es.select case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTS
ti dirà se una query ha restituito risultati. per esempio:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN
viene utilizzato per confrontare un valore con diversi e può utilizzare valori letterali, come questo:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
Puoi anche utilizzare i risultati della query con la IN
clausola, in questo modo:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Basato sull'ottimizzatore delle regole :
EXISTS
è molto più veloce di IN
quando i risultati della sottoquery sono molto grandi.IN
è più veloce di EXISTS
quando i risultati della query secondaria sono molto piccoli.Basato sull'ottimizzatore dei costi :
Suppongo che tu sappia cosa fanno, e quindi vengano usati in modo diverso, quindi comprenderò la tua domanda come: quando sarebbe una buona idea riscrivere l'SQL da usare IN invece di EXISTS, o viceversa.
È un presupposto giusto?
Modifica : il motivo per cui sto chiedendo è che in molti casi è possibile riscrivere un SQL basato su IN per utilizzare un EXISTS, e viceversa, e per alcuni motori di database, Query Optimizer tratterà i due in modo diverso.
Per esempio:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
può essere riscritto in:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
o con un join:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Quindi la mia domanda è ancora valida: il poster originale si chiede cosa faccia IN e EXISTS, e quindi come usarlo, o chiede se riscrivere un SQL usando IN per usare EXISTS, o viceversa, sarà una buona idea?
JOIN
, avrai bisogno di unDISTINCT
EXISTS
è molto più veloce di IN
quando i risultati della subquery sono molto grandi.
IN
è più veloce di EXISTS
quando i risultati della subquery sono molto piccoli.
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'
Query 1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
Query 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
Se nel t1
tuo ID ha valore nullo, la query 1 li troverà, ma la query 2 non può trovare i parametri null.
Voglio dire, IN
non è possibile confrontare nulla con null, quindi non ha alcun risultato per null, ma EXISTS
può confrontare tutto con null.
Se si utilizza l' IN
operatore, il motore SQL eseguirà la scansione di tutti i record recuperati dalla query interna. D'altra parte, se lo stiamo utilizzando EXISTS
, il motore SQL interromperà il processo di scansione non appena avrà trovato una corrispondenza.
IN supporta solo le relazioni di uguaglianza (o disuguaglianza quando precedute da NOT ).
È sinonimo di = any / = some , ad es
select *
from t1
where x in (select x from t2)
;
EXISTS supporta tipi diversi di relazioni, che non possono essere espresse utilizzando IN , ad es.
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 || '℅'
)
;
Le presunte differenze tecniche e prestazionali tra EXISTS e IN possono derivare da implementazioni / limitazioni / bug specifici del fornitore, ma molte volte non sono altro che miti creati a causa della mancanza di comprensione dei database interni.
La definizione delle tabelle, l'accuratezza delle statistiche, la configurazione del database e la versione dell'ottimizzatore hanno tutti un impatto sul piano di esecuzione e quindi sulle metriche delle prestazioni.
La Exists
parola chiave valuta vero o falso, ma la IN
parola chiave confronta tutti i valori nella corrispondente colonna secondaria. Un altro Select 1
può essere utilizzato con il Exists
comando. Esempio:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Ma IN
è meno efficiente e Exists
più veloce.
Penso,
EXISTS
è quando è necessario abbinare i risultati della query con un'altra sottoquery. I risultati della query n. 1 devono essere recuperati in corrispondenza dei risultati di SubQuery. Tipo di join ... Ad esempio, selezionare la tabella clienti n. 1 che ha effettuato anche ordini tabella n. 2
IN serve per recuperare se il valore di una colonna specifica si trova in IN
un elenco (1,2,3,4,5) Ad esempio, selezionare i clienti che si trovano nei seguenti codici zip, ovvero i valori zip_code si trovano nell'elenco (....).
Quando usarlo l'uno sull'altro ... quando ritieni che legga in modo appropriato (comunica meglio l'intento).
La differenza sta qui:
select *
from abcTable
where exists (select null)
La query sopra restituirà tutti i record mentre quella sotto restituirà vuota.
select *
from abcTable
where abcTable_ID in (select null)
Provalo e osserva l'output.
Quale è più veloce dipende dal numero di query recuperate dalla query interna:
EXIST valuta su vero o falso ma IN confronta valori multipli. Quando non sai che il record esiste o meno, dovresti scegliere ESISTERE
Il motivo è che l'operatore EXISTS lavora in base al principio "almeno trovato". Restituisce vero e interrompe la scansione della tabella una volta trovata almeno una riga corrispondente.
D'altra parte, quando l'operatore IN viene combinato con una sottoquery, MySQL deve prima elaborare la sottoquery e quindi utilizzare il risultato della sottoquery per elaborare l'intera query.
La regola generale è che se la subquery contiene un grande volume di dati, l'operatore EXISTS fornisce prestazioni migliori.
Tuttavia, la query che utilizza l'operatore IN sarà più veloce se il set di risultati restituito dalla sottoquery è molto piccolo.
La mia comprensione è che entrambi dovrebbero essere gli stessi purché non si tratti di valori NULL.
Lo stesso motivo per cui la query non restituisce il valore per = NULL vs è NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
Per quanto riguarda l'argomento booleano vs comparatore, per generare un valore booleano è necessario confrontare entrambi i valori ed è così che funziona qualsiasi condizione if. Quindi non riesco a capire come IN ed EXISTS si comportino diversamente.
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
Se una sottoquery restituisce più di un valore, potrebbe essere necessario eseguire la query esterna, se i valori all'interno della colonna specificata nella condizione corrispondono a qualsiasi valore nel set di risultati della sottoquery. Per eseguire questa attività, è necessario utilizzare la in
parola chiave.
È possibile utilizzare una sottoquery per verificare l'esistenza di un set di record. Per questo, è necessario utilizzare la exists
clausola con una sottoquery. La exists
parola chiave restituisce sempre il valore vero o falso.
Credo che questa abbia una risposta semplice. Perché non lo controlli dalle persone che hanno sviluppato quella funzione nei loro sistemi?
Se sei uno sviluppatore MS SQL, ecco la risposta direttamente da Microsoft.
IN
:
Determina se un valore specificato corrisponde a qualsiasi valore in una sottoquery o in un elenco.
Specifica una sottoquery per verificare l'esistenza di righe.
Ho scoperto che l'uso della parola chiave EXISTS è spesso molto lento (questo è vero in Microsoft Access). Al contrario, utilizzo l'operatore join in questo modo: should-i-use-the-keyword-esiste-in-sql
EXISTS ha prestazioni più veloci di IN. Se la maggior parte dei criteri di filtro si trova nella sottoquery, è meglio usare IN e Se la maggior parte dei criteri di filtro è nella query principale, allora è meglio usare EXISTS.
Se si utilizza l'operatore IN, il motore SQL eseguirà la scansione di tutti i record recuperati dalla query interna. D'altra parte se stiamo usando EXISTS, il motore SQL interromperà il processo di scansione non appena avrà trovato una corrispondenza.
IN
e EXISTS
può essere equivalente e trasformarsi l'uno nell'altro.
JOIN
in sostituzioneIN
.