如何减少PostgreSQL数据库大小?

时间:2019-04-12 15:44:56

标签: mysql postgresql types storage data-storage

我打算从MySQL迁移到PostgreSQL,因为我想利用TimescaleDB。

一切都看起来不错,直到我检查了PostgreSQL(v11.2)与MySQL(v5.6)相比使用的存储大小。对于完全相同的行数(1,440,000)和内容:

  • MySQL:156 MB
  • PostgreSQL:246 MB
  • PostgreSQL + TimescaleDB(分区/分块数据):324 MB

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 个答案:

答案 0 :(得分:3)

在您的情况下,添加timestamp列应不超过11​​ MB(1440000 * 8字节,未添加填充)。

在测量尺寸之前,您是否在Postgres中运行了 VACUUM FULL ,以便进行合理的比较?我怀疑表和索引膨胀。

相关:

在MySQL中,数据类型 float 是占用 4个字节的单精度浮点类型。

在Postgres中,相同的float是双精度浮点类型,占用 8个字节(别名:float8double precision)。

那应该解释另外44 MB的差异。要将苹果与苹果进行比较,请创建带有4字节 real 列(别名为float4)的Postgres表。注意与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中替换两者-在这种特殊情况下,它所替换的两个索引中的 one 所占磁盘空间相同(在给定的规格下可节省约50 MB)。

create index ix_cell_pid on cell( parent_id, instance_id );

考虑:

答案 1 :(得分:1)

除了Erwin Brandstetter的回答:

通常还有一些隐藏的系统列要考虑(用于实现MVCC)以及其他元组信息,例如提示位(用于缓存行可见性)。

您可以使用pageinspect扩展名查看此信息,例如:

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

有关系统列的说明,请参见here

您的索引也将包含空白,以允许更快地插入更多的元组。在CREATE INDEX docs中查找“ fillfactor”。