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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了postgres表中列的顺序是否会影响性能?相关的知识,希望对你有一定的参考价值。

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

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

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时,它是按照指定的列顺序进行的,还是按字符对齐或性能的最佳顺序重新组织列?

答案

Question 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,部分原因是这些。

Question 2

当postgres执行CREATE TABLE时,它是按照指定的列顺序进行的,还是以最佳顺序重新组织列以进行字节对齐或性能?

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

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

另一答案

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

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

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

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

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

以上是关于postgres表中列的顺序是否会影响性能?的主要内容,如果未能解决你的问题,请参考以下文章

列存储索引中列的顺序在 SQL Server 2012 中是不是重要

将 postgres 中列的值更新为小写

COUNT() 对表中列的影响

如何检查我的表中列的任何值是不是包含 MS ACCESS 2003 中的尾随空格?

是否有任何其他选项可以从表中获取总计数和同一查询中列的不同计数?

更改增量表中列的数据类型