sql >> Database teknologi >  >> RDS >> Mysql

Kan jeg tvinge mysql til at udføre underforespørgsel først?

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 .



  1. Fejl under udførelse af ODCIEXTTABLEOPEN callout

  2. MySQL Workbench viser ikke forespørgselsresultater

  3. Skift og nulstil MySQL root-adgangskode

  4. Postgres:modificer hvert array-element