2010-11-19 71 views

回答

31

NULL列不存储。该行在开始时有一个位图,每列有一个位表示哪些是空或非空。如果所有列在一行中都是非空的,则可以省略位图。因此,对于具有一个或多个零点的任何给定行,添加到其中的大小应该是位图的大小(N列表的N位向上舍入)。

在深入讨论更多从文档here

0

应该需要1个字节(0×00),但它是弥补了大部分空间的表结构,增加这个值可能会改变的东西(如添加一列),这需要更多的空间比它的数据总和。

编辑:拉勒米似乎知道比我更了解空:)

30

Laramie是正确的关于位图和他链接到手册中的正确的地方。然而,这几乎是,但不完全正确的:

因此,对于具有一个或多个空任何给定行,添加到它 规模将是位图(N位对于N列的表格,向上取整)。

必须考虑数据对齐。 HeapTupleHeader(每行)长度为23个字节,实际列数据始终以MAXALIGN(通常为8个字节)的倍数开始。这就留下了一个可以被空位图使用的填充字节。实际上对于多达8列的表,NULL存储是完全免费的。

之后,为下一个MAXALIGN * 8(通常为64)列分配另一个MAXALIGN(通常为8)字节。等等总是用于用户列的总数(全部或全部为空)。但是,只有当行中至少有一个实际的NULL值时。

我运行了大量的测试来验证所有这些。更多细节:

+2

添加列没有默认值大的表通常是一个快速的操作。跨越8列和9列之间的阈值(或者使用'MAXALIGN = 8'时为72和73')会慢吗? – 2016-09-28 17:35:26

+1

@ PatrickBrinich-Langlois:是的,这是该机制的一个可能后果。在这些情况下,物理表的大小也会超​​过人们所预期的。由于涉及死元组等其他因素,效果不一定是线性的。如果现有的NULL位图(每行)有空间存放另一个NULL位,则表格根本无法生长,这是常见情况。 – 2017-07-11 14:51:25