Дані таблиці лежать у сторінках по 8 КБ, і рядок має вміщатися в одну сторінку. TOAST (The Oversized-Attribute Storage Technique) - механізм для значень, що не вміщаються: довгих текстів, великих jsonb, масивів, bytea.
Як це працює: коли рядок перевищує поріг (~2 КБ), PostgreSQL:
- спершу стискає великі значення (алгоритм
pglzабоlz4з PostgreSQL 14); - якщо рядок досі завеликий - виносить значення в окрему TOAST-таблицю, розрізавши на шматки, а в основному рядку лишає вказівник.
Усе це прозоро: запити працюють як зазвичай.
Наслідки для продуктивності:
SELECT *дорожчий, ніж здається: для кожного рядка, де є «тостоване» значення, база читає й розпаковує його з окремої таблиці. Запит списку статей, який вибирає йbody, читає всі тексти. Вибирайте лише потрібні колонки.- Таблиця лишається компактною: основні сторінки містять короткі рядки, тож сканування за іншими колонками швидке, навіть якщо в таблиці гігабайти тексту.
- Оновлення інших колонок не переписує великі значення: якщо
bodyне змінювався, нова версія рядка посилається на ті самі TOAST-дані. - Великий
jsonb, з якого читають одне поле, все одно розпаковується цілком. Тому часті запити до поля великого JSON краще перевести на згенеровану колонку чи окреме поле.
Налаштування:
ALTER TABLE documents ALTER COLUMN body SET COMPRESSION lz4; -- швидше стискання й розпаковування
ALTER TABLE files ALTER COLUMN content SET STORAGE EXTERNAL; -- не стискати (вже стиснені дані)
Ліміт: одне значення може бути до 1 ГБ. Але зберігати великі файли в базі зазвичай погана ідея - для них об'єктне сховище (S3), а в базі - шлях і метадані.
Як подивитися розмір: pg_total_relation_size() включає TOAST і індекси, pg_relation_size() - лише основну таблицю.