Ofwel het artikel dat je las, gebruikte een slecht voorbeeld, of je interpreteerde hun punt verkeerd.
select username from users where company = 'bbc' or company = 'itv';
Dit komt overeen met:
select username from users where company IN ('bbc', 'itv');
MySQL kan een index gebruiken op company
voor deze vraag prima. Het is niet nodig om een UNION te doen.
Het lastigere geval is dat je een OR
. hebt aandoening waarbij twee verschillende . betrokken zijn kolommen.
select username from users where company = 'bbc' or city = 'London';
Stel dat er een index is op company
en een aparte index op city
. Aangezien MySQL gewoonlijk slechts één index per tabel in een bepaalde query gebruikt, welke index moet het dan gebruiken? Als het de index gebruikt op company
, zou het nog steeds een tabelscan moeten doen om rijen te vinden waar city
is Londen. Als het de index op city
gebruikt , zou het een tabelscan moeten doen voor rijen waar company
is bbc.
De UNION
oplossing is voor dit soort gevallen.
select username from users where company = 'bbc'
union
select username from users where city = 'London';
Nu kan elke subquery de index gebruiken voor zijn zoekopdracht, en de resultaten van de subquery worden gecombineerd door de UNION
.
Een anonieme gebruiker stelde een bewerking voor op mijn antwoord hierboven, maar een moderator verwierp de bewerking. Het had een reactie moeten zijn, geen edit. De claim van de voorgestelde bewerking was dat UNION de resultatenset moet sorteren om dubbele rijen te elimineren. Dit zorgt ervoor dat de query langzamer verloopt en de indexoptimalisatie is daarom een wassen neus.
Mijn antwoord is dat de indexen helpen om het resultaat te verminderen tot een klein aantal rijen voordat de UNION plaatsvindt. UNION elimineert inderdaad duplicaten, maar hoeft daarvoor alleen de kleine resultatenset te sorteren. Er kunnen gevallen zijn waarin de WHERE-clausules overeenkomen met een aanzienlijk deel van de tabel, en sorteren tijdens UNION is net zo duur als gewoon de tabelscan uitvoeren. Maar het komt vaker voor dat de resultatenset wordt verminderd door de geïndexeerde zoekopdrachten, dus het sorteren is veel goedkoper dan de tabelscan.
Het verschil hangt af van de gegevens in de tabel en de termen waarnaar wordt gezocht. De enige manier om de beste oplossing voor een bepaalde zoekopdracht te bepalen, is door beide methoden te proberen in de MySQL-queryprofiler en vergelijk hun prestaties.