varchar(n)的开销是多少?


15

我想从Postgres文档中询问有关varchar(n)类型的片段的含义:

短字符串(最多126个字节)的存储要求是1个字节加上实际的字符串,其中包括在字符情况下的空格填充。较长的字符串的开销为4个字节,而不是1个字节。

假设我有一个varchar(255)字段。现在,以下语句:

  • 如果此字段包含10个字节的字符串,则开销为1个字节。因此该字符串将使用11个字节。
  • 如果该字段使用140个字节保存字符串,则开销为4个字节。因此该字符串将使用144个字节。

以上这些陈述是正确的吗?这里有人理解文档相同的方式,我不过这里有人指出的开销总是4个字节在这里

Answers:


19

毫不奇怪,该手册是正确的。但是还有更多。

例如,磁盘上的大小(在任何表中,即使未实际存储在磁盘上)也可能与内存中的大小不同。在磁盘上,如手册中所述,短varchar值(最多126个字节)的开销减少为1个字节。但是内存中的开销始终为4个字节(一旦提取了各个值)。

同样是真正的textvarcharvarchar(n)char(n) -除了char(n)是填补空白的,以n人物和你通常不希望使用它。它的有效大小在多字节编码中仍然可以变化,因为它n表示最大字符数,而不是字节数:

字符串n,长度不超过字符(不是字节)。

它们都在varlena内部使用。
"char"(带有双引号)是另一种生物,并且始终占用一个字节。
未类型化的字符串文字'foo')具有单个字节的开销。不要与类型化的值混淆!

用测试pg_column_size()

CREATE TEMP TABLE t (id int, v_small varchar, v_big varchar);
INSERT INTO t VALUES (1, 'foo', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');

SELECT pg_column_size(id)        AS id
     , pg_column_size(v_small)   AS v_small
     , pg_column_size(v_big)     AS v_big
     , pg_column_size(t)         AS t
FROM   t
UNION ALL  -- 2nd row measuring values in RAM
SELECT pg_column_size(1)
     , pg_column_size('foo'::varchar)
     , pg_column_size('12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar)
     , pg_column_size(ROW(1, 'foo'::varchar, '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'::varchar));

 id | v_small | v_big |  t
----+---------+-------+-----
  4 |       4 |   144 | 176
  4 |       7 |   144 | 176

如你看到的:

  • 3字节的字符串'foo' 在磁盘上占据4个字节,在RAM中占据7个字节(因此1个字节对4个字节的开销)。
  • 140字节的字符串“ 123 ...”在磁盘和RAM中都占用144字节(因此总是4字节的开销)。
  • 存储integer没有开销(但是有对齐要求,可能会造成填充)。
  • 该行的元组头有24字节的额外开销(对于页头中的项目指针,每个元组还有4字节的额外开销)。
  • 最后但并非最不重要的一点:小线程的开销varchar仍然只有1个字节,而尚未从行中提取出来-从行大小可以看出。(这就是为什么有时候选择整行要快一些的原因。)

有关:


1
1字节的开销仍然是索引中的1字节吗?
dvtan

1
@dtgq:索引就像表一样存储数据,所以可以。
Erwin Brandstetter,2017年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.