Потребление памяти PostgreSQL в основном связано с:
shared_buffers : постоянный объем памяти для всего экземпляра PostgreSQL, общий для всех сеансов.
work_mem Объем памяти, доступный для операций сортировки / хеширования в сеансе. Это может быть использовано несколько раз за сеанс.
Если у вас есть резервная память на вашем сервере БД, имеет смысл увеличить shared_buffers
, чтобы в памяти оставалось больше данных. Традиционно считается, что 25% доступной оперативной памяти является хорошей отправной точкой. Когда вы используете docker-compose, вы, вероятно, делитесь этим сервером с другими процессами, поэтому вы можете настроить его, чтобы учесть это.
Вы можете / должны также увеличить work_mem
, чтобы больше операций хеширования / сортировки использовали память вместо диска. work_mem
- это переменная, которую можно установить в сеансе, поэтому попробуйте несколько вещей, например, сравните следующее:
feike=# EXPLAIN (ANALYZE ON, BUFFERS ON) SELECT * FROM pg_class ORDER BY relfilenode;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Sort (cost=230.82..234.95 rows=1652 width=782) (actual time=3.149..3.477 rows=1680 loops=1)
Sort Key: relfilenode
Sort Method: quicksort Memory: 1246kB
Buffers: shared hit=126
-> Seq Scan on pg_class (cost=0.00..142.52 rows=1652 width=782) (actual time=0.015..0.627 rows=1680 loops=1)
Buffers: shared hit=126
Planning Time: 0.193 ms
Execution Time: 3.908 ms
(8 rows)
feike=# set work_mem to '64kB';
SET
feike=# EXPLAIN (ANALYZE ON, BUFFERS ON) SELECT * FROM pg_class ORDER BY relfilenode;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------
Sort (cost=1371.82..1375.95 rows=1652 width=782) (actual time=6.675..8.102 rows=1680 loops=1)
Sort Key: relfilenode
Sort Method: external merge Disk: 832kB
Buffers: shared hit=126, temp read=239 written=268
-> Seq Scan on pg_class (cost=0.00..142.52 rows=1652 width=782) (actual time=0.015..0.654 rows=1680 loops=1)
Buffers: shared hit=126
Planning Time: 0.192 ms
Execution Time: 8.993 ms
(8 rows)
Основное отличие в планах:
Sort Method: external merge Disk: 832kB
Sort Method: quicksort Memory: 1246kB
Лучший способ узнать, будет ли work_mem
полезен, это сделать:
EXPLAIN (ANALYZE ON, BUFFERS ON)
SELECT
time_bucket_gapfill('1 day', time, date_trunc('day', now() - interval '30 days'), date_trunc('day', now())) AS one_day,
country,
type_id,
min(measurement)
FROM hypertable
WHERE
entity_id='XYZ' AND
country='US' AND
time > time_bucket('1 day', now() - interval '30 days') AND
time < time_bucket('1 day', now())
GROUP BY one_day, country, type_id
И поищите любые дисковые операции.
Строка выглядит следующим образом:
Buffers: shared hit=96 read=44152
Сообщает вам о вашем shared_buffers
, сколько раз он находил то, что ему нужно (hit
) и как часто ему приходилось извлекать что-то с диска (read
).
Слишком длинный ответ, но суть в том, что вам нужно настроить размер вашего экземпляра PostgreSQL под вашу рабочую нагрузку; значения по умолчанию для PostgreSQL (очень) консервативны, что позволяет ему работать практически везде. Однако вы, похоже, хотите использовать базу данных всерьез, поэтому требуется некоторая настройка.
Некоторые инструменты, которые помогут вам сделать это: