我有7列的表格,其中有5将为空。 我将有一个空列int
, text
, date
, boolean
和money
的数据类型。 此表将包含数百万行有很多很多空值。 恐怕空值将占用的空间。
另外,你知道,如果Postgres的索引NULL值? 我想,以防止它的索引空值。
我有7列的表格,其中有5将为空。 我将有一个空列int
, text
, date
, boolean
和money
的数据类型。 此表将包含数百万行有很多很多空值。 恐怕空值将占用的空间。
另外,你知道,如果Postgres的索引NULL值? 我想,以防止它的索引空值。
基本上, NULL
值占据NULL位图的1位 。 但它不是那么简单。
(每行)的空位图是仅当在该行中的至少一个列包含一个有NULL
值。 这可能会导致在9个以上列的表一个悖论效应:第一分配NULL
值的列会占用磁盘更多的空间比写一个值到它。 相反,随着最后一列成为非空,空位被丢弃的行。
在物理上,最初为空的位图占据之间1个字节 HeapTupleHeader
(23个字节)和实际列数据或行OID
(如果仍然应该使用) -它总是在开始的倍数MAXALIGN
(通常为8个字节 )。 这使得由该初始空位图利用填充的1个字节 。
实际上NULL存储为8列或更少的表完全免费的 。
在此之后,另一个MAXALIGN
字节(通常为8)被分配为下一个MAXALIGN * 8
列(通常为64)。 等等。
更多详细信息的说明书中并根据这些相关的问题:
一旦你理解数据类型的对齐填充,您可以进一步优化存储:
但情况是罕见的,你可以节省大量的空间。 通常,这是不值得的努力。
@Daniel已经覆盖了索引的大小的影响。
无论NULL
值获得的指数或指数的类型不是至少依赖。 基本上,这是肯定的btree
和gist
的索引类型,NO的hash
,它似乎是或否 gin
取决于PostgreSQL的版本索引类型。
曾经有一个布尔列amindexnulls
在pg_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)
这将需要更少的空间,但是这是否会帮助或不符合查询的性能取决于这些查询。
我相信每一个会用一位位图中的该行。 在这里看到: http://www.postgresql.org/docs/9.0/static/storage-page-layout.html#HEAPTUPLEHEADERDATA-TABLE