
Каждая база данных Postgres имеет свой профиль нагрузки: одни в основном читают данные, другие — постоянно их записывают. Понимание этого помогает принимать решения по индексам, настройке shared_buffers, WAL, репликам чтения и агрессивности autovacuum.Чтение и запись — не одно и то жеЧтение получает страницу размером 8 КБ из shared_buffers или кэша ОС.Если страница уже закэширована, стоимость операции почти нулевая.Если её приходится читать с диска — это одно физическое чтение.С записью всё сложнее:• Изменение сначала записывается в WAL, и только после этого транзакция может быть подтверждена• При первой записи после checkpoint'а может потребоваться запись всей страницы в WAL (full page write)• Обновляются все связанные индексы• Может выполняться запись в TOAST-таблицы и TOAST-индексы• Страница данных должна находиться в памяти, поэтому запись часто включает дополнительное чтениеИз-за этого одна операция записи по стоимости ввода-вывода обычно заметно дороже одной операции чтения.Настройки для read-heavy нагрузок• shared_buffers и effective_cache_size — чем больше горячих данных помещается в памяти, тем меньше обращений к диску• Индексы на колонках из WHERE, JOIN и ORDER BY — выигрыш от ускорения чтения обычно перекрывает накладные расходы на обновление индексов• Read replicas — позволяют распределить нагрузку от SELECT-запросов без воздействия на primary-узел• EXPLAIN ANALYZE — помогает находить медленные запросы и заменять последовательное сканирование (Seq Scan) на индексное (Index Scan) там, где это оправданоНастройки для write-heavy нагрузок• Быстрые накопители (NVMe SSD, высокий IOPS) — записи нельзя обслуживать только за счёт кэша• Меньше индексов — каждый индекс приходится обновлять при записи; неиспользуемые индексы лучше удалять• HOT Updates и fillfactor — Postgres может обновлять строку без изменения индексов, если индексируемые поля не меняются и на странице есть свободное место• Настройка WAL — wal_buffers уменьшает частоту сбросов WAL, а checkpoint_tim





