🧙 Садовник: уточнил шаги, добавил проверки и обоснования. Примите, если полезно.
#1Перед любой правкой надо знать конкретный запрос. Включи лог медленных запросов:
Либо ставь расширение pg_stat_statements и смотри топ по суммарному времени:
Колонка total_exec_time важнее, чем mean_exec_time: запрос на 50 мс, выполняемый десять тысяч раз, съедает больше, чем один на четыре секунды.
- –Известен конкретный текст медленного запроса
- –Ты смотрел на суммарное время, а не только на среднее
Что искать в выводе:
| Строка в плане | Что значит |
|---|---|
Seq Scan по большой таблице | нет нужного индекса |
rows=1 в плане, actual rows=50000 | статистика устарела, нужен ANALYZE |
тот же узел с loops=200 | классическая проблема N+1 |
Sort Method: external merge Disk | не хватает work_mem |
Вывод удобно разбирать в визуализаторе — ссылка ниже.
- –Ты знаешь, есть ли Seq Scan по большой таблице
- –Проверил, не N+1 ли это
Значения по умолчанию не зависят от объёма памяти машины: shared_buffers всегда 128 МБ, work_mem — 4 МБ. На сервере с 4 ГБ это мало.
Вот как НЕ работает — именно так было написано в исходном плане:
Официальный образ postgres знает только POSTGRES_PASSWORD, POSTGRES_USER, POSTGRES_DB, POSTGRES_INITDB_ARGS, POSTGRES_HOST_AUTH_METHOD и PGDATA. Всё остальное он просто игнорирует — без единого предупреждения.
Вот как работает:
Отправная точка для расчёта: shared_buffers около 25% от памяти, effective_cache_size — 50–75%.
- –Настройки заданы через command с -c или файлом конфига
- –SHOW shared_buffers показывает новое значение, а не 128MB
Для редко меняющихся данных время жизни в 10 минут действительно мало:
Но вместе с этим обязательно сброс при записи:
Без сброса время жизни в два часа означает буквально следующее: администратор меняет телефон на сайте, обновляет страницу и видит старый. Два часа подряд.
Проверить, что кэш работает:
- –Время жизни поднято только там, где данные редко меняются
- –Каждый метод записи сбрасывает свой ключ
- –Проверено вручную: поменял через админку — сразу видно на сайте
Каждое подключение к PostgreSQL — это отдельный процесс на сервере базы. Сотня подключений — сотня процессов.
Но сначала проверь, есть ли проблема:
Если подключений десяток из ста возможных — пул не нужен, это не узкое место.
Если нужен — есть два уровня:
- Пул в самом приложении. У SQLAlchemy он включён по умолчанию — проверь
pool_sizeиmax_overflowпрежде, чем ставить что-то ещё. - Внешний пул (PgBouncer). Нужен, когда к базе ходят несколько разных приложений или много копий одного.
У PgBouncer есть важное ограничение: в режиме transaction не работают подготовленные выражения и сеансовые настройки. Для asyncpg это значит, что нужно явно отключать кэш выражений, иначе получишь плавающие ошибки под нагрузкой.
- –Проверено, что подключения действительно заканчиваются
- –Сначала посмотрели пул самого приложения
Убедитесь, что используете актуальные версии PostgreSQL и Redis, чтобы избежать проблем с совместимостью и использовать последние улучшения производительности.
Убедитесь, что все изменения в конфигурации сохранены и применены. Проверьте, что настройки, такие как shared_buffers и work_mem, установлены правильно.