sql >> Databáze >  >> RDS >> Mysql

Mohu donutit mysql, aby nejprve provedl dílčí dotaz?

SELECT  `table_1`.*
FROM    `table_1`
INNER JOIN
        `table_2` [...]
INNER JOIN
        `table_3` [...]
WHERE   `table_1`.`id` IN
        (
        SELECT  `id`
        FROM    [...]
        )
        AND [more conditions]

Pokud je vnitřní tabulka správně indexována, poddotaz zde není vůbec "prováděn" v přísném slova smyslu.

Protože dílčí dotaz je součástí IN výraz, podmínka je vložena do poddotazu a je transformována na EXISTS .

Ve skutečnosti je tento dílčí dotaz vyhodnocen v každém kroku:

EXISTS
(
SELECT  NULL
FROM    [...]
WHERE   id = table1.id
)

Ve skutečnosti to můžete vidět v podrobném popisu poskytnutém EXPLAIN EXTENDED .

Proto se nazývá DEPENDENT SUBQUERY :výsledek každého hodnocení závisí na hodnotě table1.id . Poddotaz jako takový nekoreluje, koreluje jeho optimalizovaná verze.

MySQL vždy vyhodnotí EXISTS klauzule za jednoduššími filtry (protože je mnohem snazší vyhodnotit a existuje pravděpodobnost, že poddotaz nebude vyhodnocen vůbec).

Pokud chcete, aby byl poddotaz vyhodnocen najednou, přepište dotaz takto:

SELECT  table_1.*
FROM    (
        SELECT  DISTINCT id
        FROM    [...]
        ) q
JOIN    table_1
ON      table_1.id = q.id
JOIN    table_2
ON      [...]
JOIN    table_3
ON      [...]
WHERE   [more conditions]

To přinutí poddotaz, aby vedl ve spojení, což je efektivnější, pokud je poddotaz malý ve srovnání s table_1 a méně efektivní, pokud je poddotaz velký ve srovnání s table_1 .

Pokud je na [...].id index použitý v poddotazu, bude poddotaz proveden pomocí INDEX FOR GROUP-BY .



  1. Problémy s časovým pásmem Java MySQL Timestamp

  2. Postgres Npgsql Connection Pooling

  3. Volání členské funkce fetch_assoc() na boolean

  4. Správný způsob uložení časového pásma v databázi?