Найти в Дзене
Postgres DBA

Эмпирические ориентиры для соотношения (shared_blks_hit + shared_blks_read) / shared_blks_dirtied

Характеристика: интенсивные короткие транзакции с высокой конкуренцией за данные Паттерн: каждая транзакция читает немного данных (обычно по индексам) и часто изменяет записи Характеристика: сочетание оперативных транзакций и аналитических запросов Паттерн: чтений значительно больше, чем записей, но запись происходит регулярно Характеристика: доминирование сложных аналитических запросов Паттерн: массовое сканирование больших объёмов данных с редкой пакетной записью Характеристика: полное отсутствие операций записи Паттерн: shared_blks_dirtied = 0 или крайне мало Эти диапазоны следует рассматривать как ориентировочные. Фактическая классификация должна учитывать: Для классификации рабочей нагрузки не существует общепринятых стандартных граничных абсолютных значений для суммы shared_blks_hit + shared_blks_read. Абсолютные цифры (например, "100,000 прочитанных блоков") сами по себе не информативны, поскольку полностью зависят от размера конкретной базы данных, объема данных и масштаба
Оглавление

Материал не актуален, не используется. Перенесён в архив.

Чистый OLTP (< 10:1, часто 2:1 - 5:1)

Характеристика: интенсивные короткие транзакции с высокой конкуренцией за данные

Паттерн: каждая транзакция читает немного данных (обычно по индексам) и часто изменяет записи

Смешанная нагрузка (HTAP) (10:1 - 100:1)

Характеристика: сочетание оперативных транзакций и аналитических запросов

Паттерн: чтений значительно больше, чем записей, но запись происходит регулярно

Классический OLAP (> 100:1, может достигать 1000:1 и выше)

Характеристика: доминирование сложных аналитических запросов

Паттерн: массовое сканирование больших объёмов данных с редкой пакетной записью

Система только для чтения (→ ∞, деление на ноль)

Характеристика: полное отсутствие операций записи

Паттерн: shared_blks_dirtied = 0 или крайне мало

Важное уточнение:

Эти диапазоны следует рассматривать как ориентировочные.

Фактическая классификация должна учитывать:

  1. Абсолютные значения (1000:1 при 1000 прочитанных блоках ≠ 100:1 при 10M блоков)
  2. Временные паттерны (соотношение меняется в течение суток)
  3. Дополнительные метрики (TPS, процент последовательных сканирований, конкурентность)
-2

Для классификации рабочей нагрузки не существует общепринятых стандартных граничных абсолютных значений для суммы shared_blks_hit + shared_blks_read. Абсолютные цифры (например, "100,000 прочитанных блоков") сами по себе не информативны, поскольку полностью зависят от размера конкретной базы данных, объема данных и масштаба операций.

📏 Критерии для осмысленного анализа

Чтобы оценить нагрузку, абсолютные значения нужно сравнивать с контекстом вашей системы. Предлагаю структуру анализа на основе сопоставления метрик с общим объемом данных.

Классификация на основе относительных показателей:

  • OLTP (оперативная обработка): Обработка отдельных записей (по WHERE id = ?). Значительная часть операций (shared_blks_hit) приходится на кеш. Высокое значение shared_blks_dirtied относительно shared_blks_read.
  • OLAP (аналитическая обработка): Агрегация по большим массивам данных (например, GROUP BY, оконные функции). Большое количество shared_blks_read и shared_blks_hit. Низкое значение shared_blks_dirtied.
  • Высокая нагрузка (проблемная): shared_blks_read чрезмерно высок относительно общего размера базы. Низкий процент попаданий в кеш (shared_blks_hit). Система постоянно читает с диска.

🔍 Практический метод оценки

Для осмысленной оценки нагрузки по абсолютным значениям можно использовать следующий запрос, который добавляет контекст размера базы данных:

WITH db_stats AS (

SELECT

datname,

-- Суммарный объем прочитанных блоков

SUM(shared_blks_hit + shared_blks_read) AS total_blocks_accessed,

-- Суммарный объем измененных блоков

SUM(shared_blks_dirtied) AS total_blocks_dirtied,

-- Расчет отношения

CASE

WHEN SUM(shared_blks_dirtied) > 0

THEN ROUND(SUM(shared_blks_hit + shared_blks_read)::numeric / SUM(shared_blks_dirtied), 2)

ELSE NULL

END AS read_to_dirtied_ratio

FROM pg_stat_statements pss

JOIN pg_database pd ON pss.dbid = pd.oid

GROUP BY datname

),

size_stats AS (

-- Подзапрос для оценки общего размера данных в базах (в блоках по 8KB)

SELECT

datname,

-- Примерная оценка размера данных (требует доработки под вашу схему)

(SELECT SUM(pg_total_relation_size(oid)) / 8192

FROM pg_class

WHERE relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public')

) AS estimated_blocks

FROM pg_database

WHERE datname NOT LIKE 'template%'

)

SELECT

ds.datname,

ds.total_blocks_accessed,

ds.total_blocks_dirtied,

ds.read_to_dirtied_ratio,

ss.estimated_blocks,

-- Ключевой показатель: какой процент от общего объема данных был прочитан?

CASE

WHEN ss.estimated_blocks > 0

THEN ROUND((ds.total_blocks_accessed::numeric / ss.estimated_blocks * 100)::numeric, 4)

ELSE NULL

END AS percent_of_db_accessed,

-- Грубая классификация на основе процента

CASE

WHEN ds.total_blocks_dirtied = 0 THEN 'READ_ONLY'

WHEN (ds.total_blocks_accessed::numeric / ss.estimated_blocks) > 0.5 THEN 'POTENTIAL_OLAP'

WHEN ds.read_to_dirtied_ratio < 10 THEN 'POTENTIAL_OLTP'

ELSE 'MIXED'

END AS workload_hint

FROM db_stats ds

LEFT JOIN size_stats ss ON ds.datname = ss.datname

WHERE ds.datname IS NOT NULL

ORDER BY ds.total_blocks_accessed DESC;

Как интерпретировать результат:

  • percent_of_db_accessed: Прочитано 50% и более от общего объема данных за период? Это указывает на аналитическую (OLAP) нагрузку.
  • workload_hint: Автоматическая подсказка на основе порогов, требует проверки на ваших данных.

💡 Рекомендации по использованию метрик

Комбинируйте метрики: Отношение чтения/записи — лишь один индикатор. Важны также:

  • blk_read_time / blk_write_time: фактическое время ввода-вывода.
  • Среднее время выполнения запроса (mean_exec_time).
  • Количество строк, обработанных за вызов (rows/calls).

📚 Источники

  1. Официальная документация PostgreSQL по pg_stat_statements — первичный источник, описывающий все столбцы, включая shared_blks_hit, shared_blks_read и shared_blks_dirtied.
  2. Статья "Understanding PostgreSQL Query Performance" от pgDash — объясняет, как интерпретировать показатели блоков для анализа производительности запросов.
  3. Блог "Queries for pg_stat_statements" от pgMustard — содержит практические примеры запросов для анализа нагрузки через статистику буферов.

Ваш вопрос затрагивает интересную область, где универсальных стандартов нет, но есть устоявшаяся практика анализа через контекст и относительные показатели. Используя предложенный метод, вы сможете выявить реальные паттерны нагрузки именно в вашей системе.