Какие проблемы в SQL запросах стоит искать в первую очередь
Что проверяют
Есть ли у вас порядок действий, когда запрос тормозит или возвращает не то. Интервьюер ждёт не список «всё плохое в SQL», а приоритеты и инструменты. Следом почти всегда просят показать, как вы читаете план выполнения.
Как отвечать
Начните с того, что сначала надо найти проблемные запросы: pg_stat_statements или журнал медленных запросов в базе, а на стороне Java статистика Hibernate (hibernate.generate_statistics) или datasource-proxy, который считает запросы на один HTTP-вызов. Дальше по частоте:
- N+1: один запрос за списком и ещё по одному на каждый элемент из-за ленивых связей. Лечится
JOIN FETCH,@EntityGraphили batch fetching; - полное сканирование: под фильтр нет индекса или он есть, но не используется. Смотрите
EXPLAIN (ANALYZE, BUFFERS):Seq Scanпо большой таблице и расхождение ожидаемого и реального числа строк; - функция или приведение типа над колонкой:
WHERE lower(email) = ?или сравнение строковой колонки с числом отключают обычный индекс; - лишние данные:
SELECT *и загрузка сущностей целиком там, где хватит DTO-проекции из трёх полей; - пагинация через
OFFSET: на глубоких страницах база читает и отбрасывает все предыдущие строки, лучше keyset-пагинация поidили дате; - склейка параметров в строку: SQL-инъекция. Только
PreparedStatementи параметры, в том числе в JPQL и нативных запросах; - длинные транзакции: держат блокировки и соединение из пула, остальные ждут.
Отдельно упомяните корректность: NOT IN по подзапросу, в котором есть NULL, вернёт пустой результат, а условие = NULL никогда не бывает истинным.
Где спотыкаются
Отвечают «добавлю индексы», не посмотрев план. Индекс по колонке с низкой селективностью планировщик проигнорирует, а запись он замедлит.
Считают, что ORM сам по себе защищает от инъекций. Строка JPQL, склеенная из пользовательского ввода, уязвима так же, как обычный SQL.
Путают EXPLAIN и EXPLAIN ANALYZE: второй реально выполняет запрос, и запускать его на UPDATE или DELETE в проде без транзакции с откатом опасно.