Postgres中整数列与布尔列的磁盘使用情况

Sot*_*tis 8 postgresql performance database-design optimization disk-space postgresql-performance

我看到了这个问题Bit vs. Boolean columns

对于 Postgres,我问自己同样的问题:一位整数列是否占用了布尔值列的相同磁盘空间?在大表(约 50 列 x 约 5000 万行)中,哪一个表现最好?我怎样才能找到这个?

Lau*_*lbe 12

您可以通过以下方式找到存储大小

SELECT typname, typlen FROM pg_type WHERE typname IN ('bool', 'int4');

 typname | typlen 
---------+--------
 bool    |      1
 int4    |      4
(2 rows)
Run Code Online (Sandbox Code Playgroud)

但是,您需要考虑对齐

SELECT typname, typlen, typalign FROM pg_type WHERE typname IN ('bool', 'int4');

 typname | typlen | typalign 
---------+--------+----------
 bool    |      1 | c
 int4    |      4 | i
(2 rows)
Run Code Online (Sandbox Code Playgroud)

c是“字符”(1 个字节),i而是“整数”。

如果你定义一个这样的表:

CREATE TABLE a (
   b boolean,
   i integer
);
Run Code Online (Sandbox Code Playgroud)

您将在列之间获得三个未使用的“填充”字节,以便整数可以存储在可被 4 整除的地址处。

所以这boolean将占用 4 个而不是 1 个字节的存储空间。

如果以相反的方式指定列,则每行中的数据占用的空间仅为 5 个字节。

表行本身(“元组”)不仅包含原始数据,而且每行都有一个 23 字节的“元组标题”(请参阅文档)。标头之后可能会有填充,以便实际元组数据以倍数MAXALIGN(通常为 8)对齐。

因此,如果要优化表以使用尽可能少的存储空间,则需要考虑表中列的顺序。

  • 对。但是,通常情况下,当您进行物理设计时,这将是您最不考虑的因素。不要过早地精简和保存 - 例如,将人工主键声明为 `bigint` 比使用 `integer` 更好(比抱歉更安全)。或者记住 Y2K,它来自将年份存储为两位数。也就是说,仔细对齐列可以节省一些空间。 (2认同)
  • 标头也对齐到 4 字节吗?如果是,则该顺序不会节省示例中的任何空间,因为元组后面有 3 个未使用字节的间隙。 (2认同)
  • @bokan 非常正确。如果您有很多列,通常只能节省一些空间。 (2认同)