Самый компактный и быстрый способ хранения моей строки в PostgreSQL - PullRequest
2 голосов
/ 22 июня 2010

У меня есть большой шестнадцатеричный (16 байт, 32 шестнадцатеричных) элемент данных, который всегда имеет формат:

00d980113901429fa6de7fb7e2da705a

Это приходит как строка ASCII из моего источника (то есть ноль вышеэто символ ноль 0x30, а не 0x00), и я хотел бы узнать мнение людей о наилучшем способе (irt storage и speed) сохранить его в PostgreSQL.

Очевидная вещь, которую нужно сделать, это просто сохранить еекак varchar, но хранение его в двоичном виде определенно сэкономит место.Могу ли я увидеть выигрыш в производительности от выбора и вставки, сохранив его в двоичном виде?Байта или немного лучше?Есть ли разница между этими двумя понятиями с точки зрения внутреннего представления?

Другая идея заключается в том, чтобы хранить его как два bigint / int8 или четыре целых числа / int4, разделенные на несколько столбцов.

Пробели время - проблема, поскольку у меня есть МНОГИЕ из них (свыше триллиона).

Ответы [ 3 ]

3 голосов
/ 23 июня 2010

Сравните эти две таблицы 10M записей:

create table test (a int8 not null, b int8 not null, primary key(a,b));
insert into test
  select generate_series(1,10000000), generate_series(1,10000000);
select pg_size_pretty(pg_total_relation_size('test'));
<b>723 MB</b>
create table test_bytea (a bytea not null);
insert into test_bytea
  select decode(lpad(to_hex(a),16,'0')||lpad(to_hex(b),16,'0'),'hex') from test;
alter table test_bytea add primary key (a);
select pg_size_pretty(pg_total_relation_size('test_bytea'));
<b>804 MB</b>

A bytea с индексом на 11% больше, чем 2*int8. Это немного, но это означает, что в кэше будет на 11% меньше строк. И последовательное сканирование будет на 11% медленнее и т. Д.

Если ваши данные не меняются, возможно, вам следует рассмотреть вопрос о хранении отсортированных значений в плоском файле вместо базы данных - это будет всего 152 МБ на 10 М записей, а поиск будет O (log (n)).

1 голос
/ 23 июня 2010

Я подозреваю, что BYTEA будет в 2 раза меньше для пространства и в 2 раза быстрее для сравнения (>, <, =) по сравнению с представлением VARCHAR. </p>

В других движках базы данных вы даже можете избежать издержек на заголовок длины,Например:

MS-SQL:   BINARY(16)
Oracle:   RAW(16)
MySQL:    BINARY(16)

Или, если вам нравятся длины-заголовки:

MS-SQL:   VARBINARY(16)
Oracle:   BLOB
MySQL:    VARBINARY(16)

PostgreSQL поддерживает только BYTEA, поэтому вы всегда платите за длину-заголовок, но я все равно использую BYTEAв этой ситуации.

1 голос
/ 22 июня 2010

Вы должны определить, какое наиболее распространенное использование данных, чтобы определить соответствующий тип данных. Преобразование из типа данных означает, что индекс, ссылающийся на столбец, бесполезен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...