不要空列占据PostgreSQL的额外的空间?(Do nullable columns occupy

2019-06-17 21:52发布

我有7列的表格,其中有5将为空。 我将有一个空列inttextdatebooleanmoney的数据类型。 此表将包含数百万行有很多很多空值。 恐怕空值将占用的空间。

另外,你知道,如果Postgres的索引NULL值? 我想,以防止它的索引空值。

Answer 1:

基本上, NULL值占据NULL位图的1位 。 但它不是那么简单。

(每行)的空位图是仅当在该行中的至少一个列包含一个有NULL值。 这可能会导致在9个以上列的表一个悖论效应:第一分配NULL值的列会占用磁盘更多的空间比写一个值到它。 相反,随着最后一列成为非空,空位被丢弃的行。

在物理上,最初为空的位图占据之间1个字节 HeapTupleHeader (23个字节)和实际列数据或行OID (如果仍然应该使用) -它总是在开始的倍数MAXALIGN (通常为8个字节 )。 这使得由该初始空位图利用填充的1个字节

实际上NULL存储为8列或更少的表完全免费的
在此之后,另一个MAXALIGN字节(通常为8)被分配为下一个MAXALIGN * 8列(通常为64)。 等等。

更多详细信息的说明书中并根据这些相关的问题:

  • 需要多少磁盘空间来存储使用PostgreSQL数据库NULL值?
  • 不使用PostgreSQL的NULL仍然使用在头一个NULL位图?
  • 我多少记录可以在5 MB的PostgreSQL在Heroku存储?

一旦你理解数据类型的对齐填充,您可以进一步优化存储:

  • 计算和PostgreSQL的节省空间

但情况是罕见的,你可以节省大量的空间。 通常,这是不值得的努力。

@Daniel已经覆盖了索引的大小的影响。



Answer 2:

无论NULL值获得的指数或指数的类型不是至少依赖。 基本上,这是肯定btreegist的索引类型,NOhash ,它似乎是或否 gin取决于PostgreSQL的版本索引类型。

曾经有一个布尔列amindexnullspg_catalog.pg_am是携带的信息表,但它的消失在9.1。 可能是因为指标已经得到甚至PG改进中更复杂。

在您的数据的特定情况下,要知道最好的办法是测量索引的大小差异,使用pg_relation_size('index_name')功能,内容完全空和完全NOT NULL之间,与你的确切PG版本,确切的数据类型,精确索引类型和定义。 并知道可能的话,在这些参数的未来变化可能改变结果。

但在任何情况下,如果你“只是”想避免索引空值,它总是可以创建一个部分索引:

CREATE INDEX partial_idx(col) ON table WHERE (col is not null)

这将需要更少的空间,但是这是否会帮助或不符合查询的性能取决于这些查询。



Answer 3:

我相信每一个会用一位位图中的该行。 在这里看到: http://www.postgresql.org/docs/9.0/static/storage-page-layout.html#HEAPTUPLEHEADERDATA-TABLE



文章来源: Do nullable columns occupy additional space in PostgreSQL?