Между текстом SQL и строками результата запрос проходит конвейер.
Пять стадий
- Разбор (parse) - текст по грамматике превращается в дерево разбора; ловятся синтаксические ошибки. Существование таблиц ещё не проверяется.
- Анализ (analyze) - имена связываются с каталогом, проверяются
типы и права, раскрывается
*. Результат - дерево запроса. Здесь рождается ошибка «column does not exist». - Переписывание (rewrite) - система правил раскрывает представления и применяет RLS (см. query-rewrite).
- Планирование (plan) - выбор самого дешёвого способа выполнить; результат - дерево плана (см. cost-model).
- Выполнение (execute) - исполнитель идёт по дереву и выдаёт строки.
Что и как
Стадии 1-3 описывают, что нужно получить, стадия 4 - как. Один текст всегда даёт одно дерево запроса, но план зависит от данных и статистики и может меняться. Поэтому «вдруг стало медленно» почти всегда значит «сменился план», а не «изменился запрос».
Простой и расширенный протокол
Простой протокол выполняет всё за раз. Расширенный (Parse / Bind / Execute) разделяет стадии: разобрать один раз, выполнять много с разными параметрами. Это открывает дорогу кешу плана (см. join-order-geqo).
EXPLAIN SELECT * FROM flights WHERE departure = 'SVO';