为啥 PostgreSQL(timescaledb) 在表中花费更多的存储空间?

Posted

技术标签:

【中文标题】为啥 PostgreSQL(timescaledb) 在表中花费更多的存储空间?【英文标题】:Why PostgreSQL(timescaledb) costs more storage in table?为什么 PostgreSQL(timescaledb) 在表中花费更多的存储空间? 【发布时间】:2017-11-23 21:53:01 【问题描述】:

我是数据库新手。最近开始使用timescaledb,它是PostgreSQL中的一个扩展,所以我猜这也是PostgreSQL相关的。

我观察到一个奇怪的行为。我计算了我的表结构,1 个时间戳,2 个双精度,所以每行总共 24 个字节。我从 csv 文件导入(通过 psycopg2 copy_from)2,750,182 行。我手动计算的大小应该是 63MB,但是我查询 timescaledb,它告诉我表大小是 137MB,索引大小是 100MB,总大小是 237MB。我期待表格大小应该等于我的计算,但事实并非如此。有什么想法吗?

【问题讨论】:

(1) postgresql.org/docs/10/static/storage-file-layout.html (2) postgresql.org/docs/10/static/storage-page-layout.html Postgres 有一个 23 字节的行头。所以每一行都是 47 个字节,而不是你计算的 24 个字节。然后你还需要考虑padding 如果您担心存储空间,请尝试将数据存储到具有磁盘数据压缩的专用时间序列数据库中,例如InfluxDB 或VictoriaMetrics。与 TimescaleDB 相比,它们通常需要更少的存储空间。例如,与 TimescaleDB 相比,VictoriaMetrics 在TSBS benchmark 中使用的存储空间减少了 70 倍。 TimescaleDB 现在支持原生压缩(例如,valyala 留下的比较不再适用):blog.timescale.com/blog/… 【参考方案1】:

您的桌子比您预期的要大有两个基本原因: 1. Postgres 中的每个元组开销 2. 索引大小

    每个元组开销: An answer to a related question goes into detail that I won't repeat here 但基本上 Postgres 每行使用 23 个(+填充)字节用于各种内部事物,主要是多版本并发控制(MVCC)管理(Bruce Momjian has some good intros,如果你想了解更多信息)。这让您非常接近您所看到的 137 MB。其余的可能是由于表的填充因子设置,或者表中仍然包含任何死行,例如先前的插入和随后的删除。 索引大小: 与其他一些 DBMS 不同,Postgres 不会围绕索引在磁盘上组织其表,除非您在索引上手动对表进行集群,即使那样它也不会随着时间的推移保持集群(参见 @ 987654323@)。而是将其索引分开保存,这就是为什么索引有额外空间的原因。如果磁盘大小对您来说真的很重要,并且您没有将索引用于执行唯一性约束,那么您可能会考虑使用 BRIN 索引,尤其是当您的数据按某种顺序进入时(请参阅https://www.postgresql.org/docs/10/static/brin-intro.html)。

【讨论】:

以上是关于为啥 PostgreSQL(timescaledb) 在表中花费更多的存储空间?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 postgresql 不使用我的 group by 聚合索引?

基于PostgreSQL的时序数据库TimescaleDB(下)

Centos7 安装 PostgreSql 14 数据库 和 timescaledb 时序库

ubuntu部署TimescaleDB

ubuntu部署TimescaleDB

Linux 上 PostgreSql 14 数据库 和 timescaledb 时序库 数据迁移测试