В каком порядке выполняются условия в SQL-запросе: сначала проверка имени или даты?
Что проверяют
Понимаете ли вы, что SQL декларативен: вы описываете результат, а порядок действий выбирает планировщик. Следом обычно спрашивают, как увидеть реальный план и какой индекс помог бы этому запросу.
Как отвечать
Разделите два уровня. Первый это логический порядок обработки частей запроса: FROM и JOIN, затем WHERE, GROUP BY, HAVING, SELECT, DISTINCT, ORDER BY, LIMIT. Из него следует, например, что псевдоним из SELECT нельзя использовать в WHERE, а в ORDER BY можно.
Второй уровень это порядок проверки условий внутри WHERE. Стандарт его не задаёт, и порядок написания ничего не гарантирует. Для WHERE name = ? AND created_at > ? планировщик смотрит на индексы и статистику:
- индекс по дате: база идёт диапазоном по
created_at, а имя проверяет у найденных строк фильтром; - индекс по имени: наоборот, сначала точное совпадение по имени;
- составной индекс: удобнее всего
(name, created_at). Колонку с равенством ставят первой, с диапазоном последней, тогда оба условия отрабатывают внутри индекса; - индексов нет: последовательное чтение таблицы, и PostgreSQL сам ставит дешёвые проверки раньше дорогих.
Проверяется это через EXPLAIN или EXPLAIN ANALYZE. Для Java-разработчика стоит добавить, что порядок предикатов в Criteria API, Spring Data или jOOQ на план тоже не влияет. Влияют типы: если параметр и колонка разного типа, база приводит колонку, и индекс по ней не работает. Классический случай: драйвер SQL Server по умолчанию шлёт строки как nvarchar, а колонка объявлена varchar.
Где спотыкаются
Рассчитывают на короткое замыкание, как в Java: WHERE qty <> 0 AND total / qty > 10. SQL не обещает проверять условия слева направо, и деление на ноль всё равно возможно. Защищаются через CASE.
Забывают, что AND связывает сильнее OR: name = 'A' OR name = 'B' AND created_at > '2026-01-01' фильтрует дату только для второго имени. Нужны скобки.
Путают логический порядок с физическим. Логически ORDER BY идёт после SELECT, но с подходящим индексом база читает строки уже отсортированными и не сортирует вовсе.