В PostgreSQL частичный индекс особенно эффективен, когда в запросах регулярно повторяется один и тот же селективный предикат
WHERE, а цель — быстро получить последние N записей по времени.Таблица:
audit_logs(id, service, level, created_at, payload JSONB)
Индекс под узкий сегмент:
CREATE INDEX idx_billing_errors
ON audit_logs (created_at DESC)
WHERE service = 'billing' AND level = 'error';
Меньший размер индекса снижает нагрузку на
buffer cache, уменьшает вероятность bloat и объём фонового обслуживания, а операции с индексом требуют меньше ресурсов.Запрос за последними ошибками за сутки:
SELECT id, created_at, payload
FROM audit_logs
WHERE service = 'billing'
AND level = 'error'
AND created_at > NOW() - INTERVAL '1 day'
ORDER BY created_at DESC
LIMIT 15;
Связка
ORDER BY created_at DESC + LIMIT позволяет планировщику сделать Index Scan и остановиться рано, как только найдено нужное количество строк.index-only scan возможен только если все нужные колонки читаются из индекса, и страницы таблицы помечены
all-visible (visibility map).Если вам действительно нужен index-only для части полей, можно использовать
INCLUDE:CREATE INDEX idx_billing_errors_top
ON audit_logs (created_at DESC)
INCLUDE (id)
WHERE service = 'billing' AND level = 'error';
Частичный индекс по JSONB boolean-предикату (когда совпадающих строк мало и условие повторяется):
CREATE INDEX idx_critical_errors
ON audit_logs (created_at DESC)
WHERE level = 'error'
AND payload @> '{"critical": true}';
И быстрый top-N:
SELECT id, service, created_at
FROM audit_logs
WHERE level = 'error'
AND payload @> '{"critical": true}'
ORDER BY created_at DESC
LIMIT 10;
🔥 Частичные индексы — простой и экономный инструмент для повторяемого узкого среза + быстрого top-N по времени.
➡️ SQL Ready | #практика