Какие рекомендации по минимизации времени выполнения запроса на большой таблице
Что проверяют
Есть ли у вас порядок действий: сначала измерить, потом менять. Следом обычно дают конкретный медленный запрос или спрашивают, как вы найдёте тормозящий запрос в приложении на Hibernate.
Как отвечать
Начните с диагностики. В PostgreSQL EXPLAIN (ANALYZE, BUFFERS) показывает фактический план, число строк и прочитанных страниц. Ищите Seq Scan по большой таблице, расхождение оценки строк с фактом, сортировку на диске. Какие запросы смотреть в первую очередь, подскажет pg_stat_statements.
Дальше рычаги:
- индекс под запрос: составной в порядке «сначала равенство, потом диапазон», покрывающий через
INCLUDE, частичный сWHEREдля горячего подмножества, индекс по выражению, если в условии функция; - меньше данных: только нужные колонки вместо
SELECT *, в JPA проекции в DTO или интерфейсы вместо целых сущностей; - пагинация по ключу:
WHERE id > :lastId ORDER BY id LIMIT 50вместо большогоOFFSET, который читает и выбрасывает все пропущенные строки; - партиционирование: по дате или ключу, чтобы планировщик отсекал лишние секции;
- статистика:
ANALYZEпосле массовой загрузки и рабочий autovacuum, иначе оценки плана врут; - предрасчёт: материализованное представление или отдельная таблица для отчётов.
Со стороны Java: убрать N+1 через JOIN FETCH или @EntityGraph, для чтения пометить транзакцию @Transactional(readOnly = true). Для выгрузки больших объёмов задайте fetchSize, а в драйвере PostgreSQL он работает только при выключенном автокоммите, иначе весь результат окажется в памяти.
Где спотыкаются
Сразу предлагают «добавить индекс» или «увеличить память базе», не посмотрев план. Без EXPLAIN ANALYZE это гадание, а лишний индекс ещё и замедлит запись.
Оборачивают колонку функцией в условии: WHERE date(created_at) = ... не использует индекс по created_at. Нужен диапазон created_at >= :from AND created_at < :to или индекс по выражению.
Ищут проблему только в базе. Часто Hibernate шлёт сотни мелких запросов через ленивые связи, каждый быстрый, а страница медленная. Включите логирование SQL или статистику Hibernate, прежде чем трогать схему.