Оптимизации подзапросов с полусоединением
MariaDB имеет набор оптимизаций, специально нацеленных на подзапросы с полусоединением.
Что такое подзапрос с полусоединением
Подзапрос с полусоединением имеет вид
SELECT ... FROM outer_tables WHERE expr IN (SELECT ... FROM inner_tables ...) AND ...
то есть, подзапрос является подзапросом IN, и он расположен в операторе WHERE. Самая важная часть здесь
при подзапросе с полусоединением нас интересуют только записи из внешних таблиц, которые имеют соответствия в подзапросе
Давайте посмотрим, почему это важно. Рассмотрим подзапрос с полусоединением:
select * from Country
where
Continent='Europe' and
Country.Code in (select City.country
from City
where City.Population>1*1000*1000);
Его можно выполнить «естественным» образом, начиная с стран Европы и проверяя, есть ли у них густонаселённые города:
Свойство полусоединения также позволяет выполнение «в обратном» порядке: мы можем начать с крупных городов и проверить, в каких странах они находятся:
Для сравнения, давайте изменим подзапрос на не-полусоединение:
select * from Country
where
Country.Continent='Europe' and
(Country.Code in (select City.country
from City where City.Population>1*1000*1000)
or Country.SurfaceArea > 100*1000 -- Added this part
);
Всё ещё возможно начать со стран и затем проверить
- есть ли у страны какие-либо крупные города
- имеет ли она большую площадь:
Обратный способ, от города к стране, невозможен. Это не полусоединение.
Разница с внутренними соединениями
Операции полусоединения похожи на обычные реляционные соединения. Однако есть разница: при полусоединениях вас не интересует, сколько совпадений во внутренней таблице имеет внешняя строка. В примере выше со странами и крупными городами Германия будет возвращена один раз, даже если у неё есть три города с населением более миллиона человек каждый.
Оптимизации полусоединений в MariaDB
MariaDB использует оптимизации полусоединений для выполнения подзапросов IN. Оптимизации включены по умолчанию. Вы можете отключить их, отключив их optimizer_switch следующим образом:
SET optimizer_switch='semijoin=off'
MariaDB имеет пять различных стратегий выполнения полусоединений:
- Оптимизация вытаскивания таблицы
- Стратегия выполнения FirstMatch
- Стратегия выполнения материализации полусоединения
- Стратегия выполнения LooseScan
- Стратегия выполнения DuplicateWeedout
См. также
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/semi-join-subquery-optimizations/