Achtergrond:
De operators EXISTS en IN worden gebruikt voor het filteren van records op basis van subquery's. Sinds de opkomst van SQL hebben ontwikkelaars te maken gehad met de keuze tussen hen, terwijl ze probeerden te begrijpen welke manier sneller werkt en in welke gevallen het gebruik ervan de voorkeur heeft.
Probleem:
De belangrijkste taak is om alleen die rijen te verkrijgen die overeenkomen met de externe of interne tabel, wat altijd cruciaal is voor de prestaties bij grote datasets. De keuze tussen EXISTS en IN hangt af van de structuur van de subquery, het aantal en de uniciteit van de geretourneerde waarden, evenals van het gebruikte DBMS.
Oplossing:
IN is doorgaans efficiënter wanneer de subquery een klein aantal unieke waarden retourneert.EXISTS heeft de voorkeur als alleen het feit van het bestaan van overeenkomende rijen belangrijk is; het is geschikt voor grote subquery's die duizenden of miljoenen rijen retourneren.NULL en verschillen in optimalisatie tussen verschillende databasebeheersystemen.Voorbeeldcode:
-- Gebruik van IN SELECT name FROM students WHERE id IN (SELECT student_id FROM enrollments WHERE course = 'SQL'); -- Gebruik van EXISTS SELECT name FROM students WHERE EXISTS (SELECT 1 FROM enrollments WHERE enrollments.student_id = students.id AND enrollments.course = 'SQL');
Belangrijkste kenmerken:
Wat gebeurt er als er NULL in de IN-subquery voorkomt?
Veel mensen denken dat IN NULL gewoon negeert, maar bij de aanwezigheid van NULL kan het resultaat onvoorspelbaar worden. Bijvoorbeeld, de query:
SELECT id FROM orders WHERE client_id IN (1, NULL, 2);
zal technisch gezien geen rijen inclusief waar client_id niet gelijk is aan 1 of 2, maar als alleen NULL in de subquery voorkomt, zal het resultaat leeg zijn.
Zijn EXISTS en IN volledig verwisselbare constructies?
Nee. Het gebruik van EXISTS is vaak sneller, omdat niet de hele subquery geanalyseerd hoeft te worden. Bovendien werkt IN niet met subquery's van meerdere kolommen, terwijl EXISTS dat wel doet, omdat de vergelijking plaatsvindt op basis van de voorwaarden in WHERE. Bijvoorbeeld:
SELECT col1 FROM t1 WHERE (col1, col2) IN (SELECT col3, col4 FROM t2);
Deze variant wordt vaak niet ondersteund, terwijl een vergelijkbare EXISTS dat wel is.
Kan IN sneller zijn dan EXISTS wanneer je werkt met geïndexeerde velden?
Ja, als de subquery klein is en er een index op het te vergelijken veld staat, kan IN sneller zijn. Maar bij grote selecties of bij afwezigheid van een index, is het omgekeerd.
Een analist heeft een rapport gemaakt met de methode IN, zonder rekening te houden met het feit dat de subquery honderden duizenden rijen met NULL retourneert. Het rapport begon minutenlang te werken en verloor soms gegevens.
Voordelen:
Dezelfde query herschreven met EXISTS met een aanvullende voorwaarde, de indexen zijn herberekend.
Voordelen: