IN_EXISTS: join order is the same, but the left IN operand refers to
IN_EXISTS: join order is the same, but the left IN operand refers to
only the first table in the join order (Country), so there are much
only the first table in the join order (Country), so there are much
fewer rows to filter by subquery re-execution.
fewer rows to filter by subquery re-execution.
EXPLAIN extended
EXPLAIN
SELECT *
SELECT *
FROM Country, City
FROM Country, City
WHERE City.Country = Country.Code AND
WHERE City.Country = Country.Code AND
...
@@ -153,12 +153,10 @@ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
...
@@ -153,12 +153,10 @@ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
(Country.Name IN
(Country.Name IN
(select Language from CountryLanguage where Percentage > 50) OR
(select Language from CountryLanguage where Percentage > 50) OR
Country.name LIKE '%Island%');
Country.name LIKE '%Island%');
id select_type table type possible_keys key key_len ref rows filtered Extra
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 19.67 Using where
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18 100.00
1 PRIMARY City ref Country Country 3 world.Country.Code 18
2 DEPENDENT SUBQUERY CountryLanguage index_subquery Percentage,Language Language 30 func 2 100.00 Using where
2 DEPENDENT SUBQUERY CountryLanguage index_subquery Percentage,Language Language 30 func 2 Using where
Warnings:
Note 1003 select `world`.`Country`.`Code` AS `Code`,`world`.`Country`.`Name` AS `Name`,`world`.`Country`.`SurfaceArea` AS `SurfaceArea`,`world`.`Country`.`Population` AS `Population`,`world`.`Country`.`Capital` AS `Capital`,`world`.`City`.`ID` AS `ID`,`world`.`City`.`Name` AS `Name`,`world`.`City`.`Country` AS `Country`,`world`.`City`.`population` AS `population` from `world`.`Country` join `world`.`City` where ((`world`.`City`.`Country` = `world`.`Country`.`Code`) and (`world`.`Country`.`SurfaceArea` < 3000) and (`world`.`Country`.`SurfaceArea` > 10) and (<expr_cache><`world`.`Country`.`Name`>(<in_optimizer>(`world`.`Country`.`Name`,<exists>(<index_lookup>(<cache>(`world`.`Country`.`Name`) in CountryLanguage on Language where ((`world`.`CountryLanguage`.`Percentage` > 50) and (<cache>(`world`.`Country`.`Name`) = `world`.`CountryLanguage`.`Language`)))))) or (`world`.`Country`.`Name` like '%Island%')))