VÆLG `table_1`.*FRA `table_1`INNER JOIN `table_2` [...]INNER JOIN `table_3` [...]HVOR `table_1`.`id` IN ( SELECT `id` FRA [...] ) OG [flere betingelser]
Hvis den indre tabel er korrekt indekseret, bliver underforespørgslen her slet ikke "udført" i en streng betydning af ordet.
Da underforespørgslen er en del af en IN
udtryk, skubbes betingelsen ind i underforespørgslen, og den transformeres til en EXISTS
.
Faktisk evalueres denne underforespørgsel på hvert trin:
FINDER(SELECT NULLFROM [...]WHERE id =table1.id)
Du kan faktisk se det i den detaljerede beskrivelse fra EXPLAIN EXTENDED
.
Det er derfor, det hedder AFHENGIG SUBQUERY
:Resultatet af hver evaluering afhænger af værdien af table1.id
. Underforespørgslen som sådan er ikke korreleret, det er den optimerede version, der er korreleret.
MySQL
evaluerer altid EXISTS
klausul efter de mere simple filtre (da de er meget nemmere at evaluere, og der er en sandsynlighed for, at underforespørgslen slet ikke vil blive evalueret).
Hvis du ønsker, at underforespørgslen skal evalueres på én gang, skal du omskrive forespørgslen som denne:
SELECT table_1.*FROM (SELECT DISTINCT id FROM [...] ) qJOIN table_1ON table_1.id =q.idJOIN table_2ON [...]JOIN table_3ON [...]WHERE [flere betingelser]
Dette tvinger underforespørgslen til at være førende i joinforbindelsen, hvilket er mere effektivt, hvis underforespørgslen er lille sammenlignet med tabel_1
, og mindre effektiv, hvis underforespørgslen er stor sammenlignet med tabel_1
.
Hvis der er et indeks på [...].id
brugt i underforespørgslen, vil underforespørgslen blive udført ved hjælp af en INDEX FOR GROUP-BY
.