Оптимизации подзапросов в InterBase - Распространённые заблуждения

ОГЛАВЛЕНИЕ

 

Распространённые заблуждения

Вообще-то это не совсем заблуждения. Точнее, во многих СУБД это никакие не заблуждения, а проза жизни. Потому во многих книгах это дело описывается, как нечто само собой разумеющееся. Потому многие люди, не разобравшись, переносят подобные утверждения на InterBase, что приводит к неожиданным и, как правило, отрицательным последствиям.

Итак, подзапросы с точки зрения их вычислимости без охватывающего запроса, делят на коррелированные и некоррелированные. Коррелированный означает "зависимый от внешнего контекста". То есть, в таком запросе, где-нибудь хотя бы раз употребляется ссылка на поле какой-либо текущей записи внешнего запроса. Таким образом, по ходу обработки всей конструкции на каждую запись внешнего запроса нужно перевычислять подзапрос.

С другой стороны, некоррелированные подзапросы построены исключительно на основе собственных таблиц и процедур и из внешнего контекста ничего не требуют. Такой запрос можно вызвать отдельно, ничего в нём не изменив. И результат такого запроса, соответственно, на одних и тех же данных постоянен. Отсюда вывод: нет смысла вызывать такой подзапрос несколько раз, достаточно при первом вызове запомнить результат, и затем использовать его для внешнего запроса.

Вот это и есть то самое заблуждение. Точнее, их тут даже два.

Некоррелированный подзапрос независим от контекста

Ну, независим-то он - независим, но это ещё не значит, что никак не связан. Фактически подзапрос всегда используется для сравнения каких-то его полей с какими-то внешними значениями. И учёт этого факта в ряде ситуаций может быть довольно успешно использован, чтобы ликвидировать часть работы во время выполнения подзапроса.

Некоррелированный подзапрос выполняется один раз

Это один из подходов, применяемых в большинстве СУБД. Однако в InterBase это правда, только для подзапросов в скалярном контексте. Для множественного контекста применяется совершенно другой подход, описанный в следующем разделе.