Как уменьшить размер базы данных PostgreSQL? - PullRequest
0 голосов
/ 12 апреля 2019

Я планировал перейти с MySQL на PostgreSQL, потому что хотел использовать TimescaleDB.

Все выглядело хорошо, пока я не проверил размер хранилища, используемого PostgreSQL (v11.2), по сравнению с MySQL (v5.6). Для точно такого же количества строк (1 440 000) и содержимого:

  • MySQL: 156 МБ
  • PostgreSQL: 246 МБ
  • PostgreSQL + TimescaleDB (разделенные / порционные данные): 324 МБ

Числа MySQL и PostgreSQL аналогичны (например, включая индексы и другие ограничения), у PostgreSQL + TimescaleDB есть накладные расходы на добавление временной метки в таблицу. Соответствующая таблица выглядит так:

create table cell(
    cell_id            serial not null
   ,ts                 timestamp not null
   ,parent_id          int references parent( parent_id )
   ,instance_id        smallint
   ,v                  float
   ,a                  float
   ,t                  float
   ,s1                 float
   ,s2                 float
   ,s3                 float
   ,s4                 float
   ,s5                 float
   ,primary key( cell_id )
);
create index ix_cell_pid on cell( parent_id );
create index ix_cell_inst on cell( instance_id );

Почему PostgreSQL занимает гораздо больше памяти, чем MySQL?
И есть ли способ значительно снизить его до уровня MySQL?

Ответы [ 2 ]

3 голосов
/ 12 апреля 2019

Добавление столбца timestamp должно добавить не более 11 МБ в вашем случае (1440000 * 8 байт, без добавления заполнения).

Вы запустили VACUUM FULL в Postgres до того, как вы измерили размер, для честного сравнения? Я подозреваю, что таблицы и индексы раздуты.

Связанный:

В MySQL тип данных float - это тип с плавающей запятой одинарной точности, занимающий 4 байта .

В Postgres тот же float - это тип с плавающей запятой двойной точности, занимающий 8 байт (псевдоним: float8 или double precision).

Это должно объяснить еще 44 МБ разницы. Чтобы сравнить яблоки с яблоками, создайте таблицу Postgres с 4-байтовыми real столбцами (псевдоним float4). Обратите внимание на разницу с MySQL, где real используется для 8-байтовых чисел с плавающей запятой! Несчастные разногласия.

Руководство по MySQL: https://dev.mysql.com/doc/refman/8.0/en/storage-requirements.html
Руководство Postgres: https://www.postgresql.org/docs/current/datatype-numeric.html

Связанный:

Вы показываете два индекса . В зависимости от того, для чего они предназначены, один многоколонный индекс может заменить оба в Postgres - занимая столько же дискового пространства, сколько один из двух, которые он заменяет в данном конкретном случае (сохранение ~ 50 МБ с заданными характеристиками).

create index ix_cell_pid on cell( parent_id, instance_id );

Рассмотрим:

1 голос
/ 15 апреля 2019

В дополнение к ответу Эрвина Брандштеттера:

Существуют также обычно скрытые системные столбцы, которые необходимо учитывать (используется для реализации MVCC) вместе с другой информацией о кортежах, такой как биты подсказок (используются для кэширования видимости строк).

Вы можете использовать расширение pageinspect для просмотра этой информации, например ::

create extension pageinspect;
select * from heap_page_items(get_raw_page('cell', 0));

См. здесь для описания системных столбцов.

Ваши индексы также будут содержать пустое пространство, чтобы можно было быстрее вставлять другие кортежи. Ищите «fillfactor» в документах CREATE INDEX .

...