postgres表中列的顺序是否会影响性能?

时间:2012-09-26 15:03:22

标签: performance postgresql database-design

在Postgres中,CREATE TABLE语句中的列顺序会影响性能吗?考虑以下两种情况:

CREATE TABLE foo (
  a      TEXT, 
  B      VARCHAR(512),
  pkey   INTEGER PRIMARY KEY,
  bar_fk INTEGER REFERENCES bar(pkey),
  C      bytea
); 

VS。

CREATE TABLE foo2 (
  pkey   INTEGER PRIMARY KEY,
  bar_fk INTEGER REFERENCES bar(pkey),
  B      VARCHAR(512),      
  a      TEXT, 
  C      bytea
);

由于列的字节对齐更好,foo2的效果会优于foo吗?当Postgres执行CREATE TABLE时,它是按照指定的列顺序进行的,还是以最佳顺序重新组织列以进行字节对齐或性能?

2 个答案:

答案 0 :(得分:22)

问题1

  

由于更好​​的字节,foo2的性能是否会优于foo   列对齐?

是的,列的顺序对性能的影响很小。类型对齐是更重要的因素,因为它会影响磁盘上的占用空间。您可以最小化存储大小(播放“列俄罗斯方块”)并在数据页上挤压更多行 - 这是速度最重要的因素。

this related answer这样的极端例子,你会得到很大的不同 通常情况下不值得打扰。

另一个因素是,如果首先使用固定大小的列,则检索列值会稍微快一些。我引用manual here

  

要读取您需要依次检查每个属性的数据。第一   根据空位图检查字段是否为NULL。如果它   是,转到下一个。然后确保你有正确的对齐方式。如果   该字段是固定宽度字段,然后所有字节都是简单的   放置。如果它是一个可变长度字段(attlen = -1)那么它有点   更复杂。所有可变长度数据类型共享公共   头结构struct varlena,包括总长度   存储的值和一些标志位。

有一个开放的TODO item to allow reordering of column positions in the Postgres Wiki,部分是出于这些原因。

问题2

  

当postgres执行CREATE TABLE时,它遵循列顺序   指定或者以字节的最佳顺序重新组织列   对齐还是表现?

列以定义的顺序存储 ,系统不会尝试优化。

我没有看到列顺序与TOAST tables的任何相关性,就像另一个答案似乎暗示的那样。

答案 1 :(得分:3)

据我了解,PostgreSQL遵循保存记录时输入列的顺序。这是否会影响性能是值得商榷的。 PostgreSQL将所有表数据存储在每个大小为8kb的页面中。 8kb是默认值,但可以在编译时更改。

表格中的每一行都占用页面内的空间。由于表定义包含变量列,因此页面可以包含可变数量的记录。您要做的是确保您可以将尽可能多的记录放入一个页面。这就是为什么当表有大量列或列大小时会发现性能下降的原因。

这就是说,声明varchar(8192)并不意味着页面将填充一个记录,但声明CHAR(8192)将占用一整页而不管列中的数据量。 / p>

在声明TOASTable类型(如TEXT列)时还有一件事需要考虑。这些列可能超过最大页面大小。具有TOASTable列的表将具有关联的TOAST表来存储数据,并且只有指向数据的指针与表一起存储。这可能会影响性能,但可以使用TOASTable列上的适当索引进行改进。

总而言之,我不得不说列的顺序在表的性能中不起作用。大多数查询使用单独存储的索引来检索记录,因此列顺序被否定。它归结为需要读取多少页来检索数据。