Ответ 1
Почему не рекомендуется использовать подзапросы?
Оптимизатор баз данных (независимо от используемой базы данных) не всегда может правильно оптимизировать такой запрос (с подзапросами). В этом случае проблема с оптимизатором заключается в выборе правильного способа объединения наборов результатов. Существует несколько алгоритмов для объединения двух наборов результатов. Выбор алгоритма зависит от количества записей, которые содержатся в одном и в другом результирующем наборе. Если вы присоединитесь к двум физическим таблицам (подзапрос - это не физическая таблица), база данных может легко определить объем данных в двух наборах результатов по доступной статистике. Если один из результирующих наборов является подзапросом, то понять, сколько записей он возвращает, очень сложно. В этом случае база данных может выбрать неправильный план запроса соединения, что приведет к резкому снижению производительности запроса.
Перезапись запроса с использованием временных таблиц предназначена для упрощения оптимизатора базы данных. В переписанном запросе все результирующие множества, участвующие в объединениях, будут физическими таблицами, и база данных будет легко определять длину каждого набора результатов. Это позволит базе данных выбрать гарантированный самый быстрый из всех возможных планов запросов. Более того, база данных сделает правильный выбор независимо от условий. Переписанный запрос с временными таблицами будет хорошо работать в любой базе данных, что особенно важно при разработке переносных решений. Кроме того, переписанный запрос легче читать, проще понимать и отлаживать.
Понятно, что переписывание запроса с временными таблицами может привести к некоторому замедлению из-за дополнительных затрат: создание временных таблиц. Если база данных не ошибается при выборе плана запроса, она будет выполнять старый запрос быстрее, чем новый. Однако это замедление всегда будет незначительным. Обычно создание временной таблицы занимает несколько миллисекунд. То есть задержка не может оказать существенного влияния на производительность системы и обычно может быть проигнорирована.
Внимание! Не забудьте создать индексы для временных таблиц. Поля индекса должны включать все поля, которые используются в условиях соединения.