(The Oversized‑Attribute Storage Technique) механизм, позволяющий выносить большие данные за пределы основной строки

PostgreSQL позволяет хранить большие данные с помощью, например, типов text или jsonb. Если итоговая строка не помещается в страницу Базы (~8 КБ), PostgreSQL попытается уменьшить её размер — сжать и если этого не хватит, БД разбивает значение на фрагменты (по ~1996 байт (~2 КБ) - это размер позволяющий гарантированно поместить фрагмент в страницу) и сохраняет эти фрагменты в отдельную TOAST‑таблицу, которая создаётся автоматически. В основной строке (куда было бы помещено простое значение) сохраняется ссылка (TOAST-указатель, а не сами данные). Когда данные запрашиваются PostgreSQL по ссылке получает фрагменты и снова собирает их.

Особенности:

  • TOAST-таблица — это обычная таблица с полями: chunk_id, chunk_seq, chunk_data
  • Механизм автоматический, включается когда строка превышает допустимый размер
  • Есть несколько стратегий сжатия и хранения (PLAIN, EXTENDED, EXTERNAL, MAIN). По умолчанию используется EXTENDED: сначала База попытается сжать данные, после чего при необходимости значение может быть вынесено в TOAST
  • Чтение TOAST‑данных немного дороже, чем чтение обычных (надо задействовать дополнительную таблицу и собирать фрагменты). Но это уменьшает размер основной таблицы и сокращает объём данных, который PostgreSQL читает при работе со строками без больших значений
  • Статистика для больших полей может быть менее точной, так как при анализе используются усечённые значения
  • Большие значения извлекаются только при обращении к ним (как lazy load)

-- Если есть TOAST то будет две строки — основная таблица и её TOAST-таблица
SELECT c.relname AS table_name,
       c.relpages,
       c.reltuples,
       pg_size_pretty(pg_total_relation_size(c.oid)) AS total_size
FROM pg_class c
WHERE c.oid = 'table_name'::regclass
   OR c.oid = (
       SELECT reltoastrelid
        FROM pg_class
       WHERE oid = 'table_name'::regclass
   );