Я использую 9.1, и у меня есть таблица с именем dpi
в базе данных с кодировкой UTF-8, которая в настоящее время находится в 18 628 строках. Есть TEXT
колонка там называется foto
который содержит строки B64, представляющие уникальный файл изображения.
Я пытаюсь выяснить, сколько места на диске занимает одна строка. Есть 18050 строк без NULL
ценность для foto
и length()
для всех из них 87384.
Я не понимаю этого. Бег select * from pgstattuple('dpi');
возвращает:
-[ RECORD 1 ]------+--------
table_len | 5890048
tuple_count | 18628
tuple_len | 5656063
tuple_percent | 96.03
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 92752
free_percent | 1.57
Бег
select pg_size_pretty(pg_relation_size(c.oid)) AS "size"
from pg_class c
where relname = 'dpi';
Получаю следующее:
size
---------
5752 kB
(1 row)
Что именно здесь происходит? Почему этот стол такой маленький?
Изменить: также я проверил /var/lib/postgresql/9.1/main
и его размер 574,5 МБ. Бег:
SELECT nspname || '.' || relname AS "relation",
pg_size_pretty(pg_relation_size(C.oid)) AS "size"
FROM pg_class C
LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE nspname NOT IN ('pg_catalog', 'information_schema')
ORDER BY pg_relation_size(C.oid) DESC
LIMIT 3;
дает:
relation | size
-------------------------------+---------
pg_toast.pg_toast_17048 | 501 MB
public.dpi | 5752 kB
pg_toast.pg_toast_17048_index | 5752 kB
(3 rows)
Изменить 2: Использование select pg_total_relation_size('dpi');
я получил 539262976
байты. Означает ли это, что я могу разделить это на 18628 и получить средний размер строки (28 КиБ)? Меняется ли этот размер для каждой строки со временем (из-за индексов или чего-то подобного)?
Даже в этом случае 28 КБ на строку кажутся исключительно маленькими. Один foto
только значение должно быть 85 КиБ (при условии, что только 1-байтовые символы).
Ответ заключается в том, что механизм TOAST PostgreSQL по умолчанию не только разбивает очень большие столбцы, в зависимости от типа данных, который он действительно пытается сначала сжать. Довольно аккуратно.
Источник: http://www.postgresql.org/docs/9.1/static/storage-toast.html
Postgresql не имеет "типа blobs". Что происходит, так это то, что он автоматически нарезает «большие столбцы» (т.е. больше 1 страницы, 8 КБ) на «всплывающие» таблицы.
Ищите здесь информация об использовании диска на postgres
и здесь для функция администратора postgresql где вы узнаете, что интересующие вас функции: pg_table_size
и pg_total_relation_size
Оба учитывают пространство для тостов. Первый не считает индексное пространство, второй - нет.