🛠️ UPDATE меняет одно поле. Почему HOT почти не срабатывает?

Условная статистика:

n_tup_upd = 18 400 000 n_tup_hot_upd = 920 000 n_dead_tup = 3 700 000

При UPDATE PostgreSQL создаёт новую версию строки. HOT позволяет не добавлять для неё записи в обычные индексы, но нужны два условия:

— обновление не меняет данные, на которые ссылаются обычные индексы; — новая версия помещается на той же heap-странице.

Например:

UPDATE orders SET processing_status = 'completed' WHERE id = :id;

Если processing_status используется обычным, составным, partial или expression index, изменение обычно исключает HOT.

Исключение — summarizing indexes: в основной поставке PostgreSQL это BRIN. Они не запрещают HOT тем же способом, хотя их сводные данные могут обновляться.

Если индекс обновлять не нужно, остаётся второй вопрос: хватает ли места на исходной странице.

Более низкий table fillfactor оставляет запас и может повысить вероятность HOT. Но это не гарантия: менее плотное размещение увеличивает число страниц, а изменение параметра само по себе не переразмещает все существующие строки.

Что проверить:

— какие запросы создают основной поток UPDATE; — какие данные используются индексами; — долю n_tup_hot_upd в n_tup_upd; — при доступности — n_tup_newpage_upd; — fillfactor и размеры отношений в динамике; — сопоставимый интервал статистики.

n_dead_tup — оценка, а не точное измерение bloat. VACUUM освобождает место dead versions для повторного использования, но не превращает будущие обновления в HOT автоматически.

Вывод: низкая доля HOT — начало диагностики, а не команда удалить индекс, снизить fillfactor или чаще запускать VACUUM.

🔹🔹🔹🔹

🛠️ UPDATE меняет одно поле. Почему HOT почти не срабатывает?
Условная статистика:
ntupupd = 18 400 000
ntuphotupd = 920 000
ndeadtup = 3 700 000
При UPDATE PostgreSQL создаёт новую версию строки | Сетка — социальная сеть от hh.ru