lesson ── postgres-labs ── ~22 мин ── 4 шагов
Положи в таблицу хорошо сжимаемое и несжимаемое значение и определи, где каждое осело. Перед каждым измерением предсказывай: останется ли значение в строке или уйдёт в TOAST-таблицу.
интерактивный sandbox
Поднимется контейнер postgreslab/postgres-base с PostgreSQL 17 и psql. В браузере откроется терминал, база lab уже настроена. Каждый шаг проверяется автоматически. Сеть air-gapped, наружу контейнер не ходит.
stack ── PostgreSQL 17 · psql · 1 GB RAM · air-gapped · самоуничтожается через 45 мин простоя
Положи пять тысяч одинаковых букв. Логически это 5000 байт - проверь.
CREATE TABLE toast_demo (id int, big text);
INSERT INTO toast_demo VALUES (1, repeat('A', 5000));SELECT octet_length(big) FROM toast_demo WHERE id = 1;
✓ Логическая длина 5000 байт.
Предскажи pg_column_size: одинаковые буквы прекрасно сжимаются. Значение длиной 5000 байт после сжатия легко влезает в строку.
SELECT pg_column_size(big) AS stored, octet_length(big) AS logical
FROM toast_demo WHERE id = 1;
Сжатый размер - десятки байт, а не тысячи.
✓ Сжалось до десятков байт и осталось в строке.
Положи случайный текст, который сжатие не берёт, - около 6400 байт. Предскажи: останется ли он в строке?
INSERT INTO toast_demo
SELECT 2, string_agg(md5(g::text), '') FROM generate_series(1, 200) g;
SELECT pg_column_size(big) AS stored, octet_length(big) AS logical
FROM toast_demo WHERE id = 2;
Если stored примерно равен logical и велик - значение вынесено без сжатия.
✓ Сжатие не помогло, значение крупное - оно вынесено наружу.
Вынесенные значения лежат в отдельной TOAST-таблице. Найди её.
SELECT reltoastrelid::regclass FROM pg_class WHERE relname = 'toast_demo';
✓ TOAST-таблица есть - в ней лежит вынесенное значение чанками.
TOAST сначала сжимает длинное значение: если влезает - оставляет в строке (5000 одинаковых букв сжались в десятки байт). Если сжатие не помогает (несжимаемые ~6400 байт), значение выносится в отдельную TOAST-таблицу.
команды
SELECT pg_column_size(big), octet_length(big) FROM t;физический размер против логическогоSELECT reltoastrelid::regclass FROM pg_class WHERE relname='t';TOAST-таблица отношенияконцепции