具有空值的XML字段的表占用了一些空间?多少?

时间:2015-12-17 21:41:44

标签: postgresql diskusage

有一个“官方基准”或简单的经验法则来决定何时会影响空间或表现?

我的表有很多简单的索引字段,

CREATE TABLE t (
  id serial PRIMARY KEY,
  name varchar(250) NOT NULL, 
  ...
  xcontent xml, -- the NULL use disk space?? cut performance?
  ...
  UNIQUE(name)
);

并且它是一种“sparse content”,许多xcontent值将为NULL ...那么,这些XML NULL会消耗一些磁盘空间吗?

备注

我可以规范化,表t现在将是nt

CREATE TABLE nt (
  id serial PRIMARY KEY,
  name varchar(250) NOT NULL, 
  ...
  UNIQUE(name)
);

CREATE TABLE nt2 (
  t_id int REFERENCES nt(id),
  xcontent xml NOT NULL
);

CREATE VIEW nt_full AS 
   SELECT nt.*, nt2.xcontnt FROM nt LEFT JOIN nt2 ON id=t_id;

那么,我需要这种复杂性吗?这个新表排列将消耗更少的磁盘空间。使用

SELECT id, name FROM nt WHERE name>'john';      -- Q1A 
SELECT id, name FROM nt_full WHERE name>'john'; -- Q1B
SELECT id, name FROM t WHERE name>'john';       -- Q1C

SELECT id, xcontent FROM nt_full WHERE name>'john'; -- Q2A
SELECT id, xcontent FROM t WHERE name>'john';       -- Q2B

所以,从理论上讲,Q1A与Q1B对Q1C的所有表现都是一样的? 和Q2A对Q2B?

2 个答案:

答案 0 :(得分:2)

“空值占用多少空间”这一问题的答案是:根本没有空间 - 至少不在“数据”区域。

对于表中的每个可空列,行标题中有一个,用于将列值标记为空(或非空)。因此,null值所采用的“空间”已存在于行标题中 - 无论该列是否为null。

因此,空“值”不占用存储该行的数据块中的任何空间。

手册中记录了这一点:http://www.postgresql.org/docs/current/static/storage-page-layout.html

如果超过某个阈值(约2000字节),Postgres将不会在实际数据块中存储长字符串值(xml,varchar,text,json,...)。如果该值超过该值,它将存储在与实际数据“相距”的特殊存储区域中。因此,将表分成两个具有1:1关系的表并不是你真的那么多。除非您存储很多行(数亿),否则我怀疑您是否能够注意到差异 - 但这也取决于您的使用模式。

“外线”存储的数据也会自动压缩。

有关此内容的详细信息,请参阅手册:http://www.postgresql.org/docs/current/static/storage-toast.html

单独的表可能成为优势的一个原因是必要的“真空”清理。如果您更新XML数据批次但表的其余部分几乎没有更改,那么将其拆分为两个表可能会提高整体性能,因为“XML表”将需要更少的“维护”和“主”表根本不会改变。

答案 1 :(得分:0)

varchar字段比内容多消耗2个字节。 所以如果你把它定义为varchar(250) 并放入10个字符,它消耗12个字节 100个字符消耗102个字节 NULL消耗2个字节。没问题。

如果您处于某种需要存储大量xml数据的情况 并最终使用(例如)blob类型,你应该把它放在另一个表中 并保持你的主表精益和快速

相关问题