Het lijkt mij dat je hetzelfde kunt doen in een SQL-query met NOT EXISTS, NOT IN of LEFT JOIN WHERE IS NULL. Bijvoorbeeld:
SELECT a FROM table1 WHERE a NOT IN (SELECT a FROM table2)
SELECT a FROM table1 WHERE NOT EXISTS (SELECT * FROM table2 WHERE table1.a = table2.a)
SELECT a FROM table1 LEFT JOIN table2 ON table1.a = table2.a WHERE table1.a IS NULL
Ik weet niet zeker of ik alle syntaxis correct heb, maar dit zijn de algemene technieken die ik heb gezien. Waarom zou ik ervoor kiezen om de ene boven de andere te gebruiken? Verschillen de prestaties…? Welke van deze is het snelst / meest efficiënt? (Als het afhangt van de implementatie, wanneer zou ik ze dan allemaal gebruiken?)
Antwoord 1, autoriteit 100%
-
NIET IN vs. NIET BESTAAN vs. LEFT JOIN / IS NULL: SQL Server
-
NIET IN vs. NIET BESTAAN vs. LEFT JOIN / IS NULL: PostgreSQL
In een notendop:
NOT IN
is een beetje anders: het komt nooit overeen als er maar één NULL
in de lijst staat.
-
In
MySQL
isNOT EXISTS
iets minder efficiënt -
In
SQL Server
isLEFT JOIN / IS NULL
minder efficiënt -
In
PostgreSQL
isNOT IN
minder efficiënt -
In
Oracle
zijn alle drie de methoden hetzelfde.
Antwoord 2, autoriteit 4%
Als de database goed is in het optimaliseren van de zoekopdracht, worden de eerste twee getransformeerd naar iets dat dicht bij de derde ligt.
Voor eenvoudige situaties zoals die in je vraag, zou er weinig of geen verschil moeten zijn, omdat ze allemaal als joins worden uitgevoerd. Bij complexere zoekopdrachten kan de database mogelijk geen join maken van de zoekopdrachten not in
en NOT EXISTS
. In dat geval worden de zoekopdrachten een stuk langzamer. Aan de andere kant kan een join ook slecht presteren als er geen index is die kan worden gebruikt, dus alleen omdat je een join gebruikt, wil nog niet zeggen dat je veilig bent. U zou het uitvoeringsplan van de query moeten onderzoeken om te zien of er prestatieproblemen zijn.
Antwoord 3
Ervan uitgaande dat u nulls vermijdt, zijn dit allemaal manieren om een anti-jointe schrijven met behulp van standaard SQL.
Een voor de hand liggende omissie is het equivalent met EXCEPT
:
SELECT a FROM table1
EXCEPT
SELECT a FROM table2
Opmerking in Oracle dat u de operator MINUS
moet gebruiken (misschien een betere naam):
SELECT a FROM table1
MINUS
SELECT a FROM table2
Over propriëtaire syntaxis gesproken, er kunnen ook niet-standaard equivalenten zijn die het onderzoeken waard zijn, afhankelijk van het product dat u gebruikt. OUTER APPLY
in SQL Server (zoiets als):
SELECT t1.a
FROM table1 t1
OUTER APPLY
(
SELECT t2.a
FROM table2 t2
WHERE t2.a = t1.a
) AS dt1
WHERE dt1.a IS NULL;
Antwoord 4
Als u gegevens in een tabel moet invoegen met een primaire sleutel met meerdere velden, denk er dan aan dat het veel sneller zal zijn (ik heb geprobeerd in Access, maar ik denk in elke database) om niet te controleren of er geen records bestaan met ‘dergelijke’ waarden in table”, – liever gewoon in de tabel invoegen, en overtollige records (met de toets) worden niet twee keer ingevoegd.
Antwoord 5
Prestatieperspectief vermijd altijd het gebruik van inverse zoekwoorden zoals NOT IN, NOT EXISTS, …
Omdat om de inverse items te controleren, DBMS door alle beschikbare moet lopen en de inverse selectie moet laten vallen.