在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
时,它是按照指定的列顺序进行的,还是以最佳顺序重新组织列以进行字节对齐或性能?
答案 0 :(得分:22)
由于更好的字节,foo2的性能是否会优于foo 列对齐?
是的,列的顺序对性能的影响很小。类型对齐是更重要的因素,因为它会影响磁盘上的占用空间。您可以最小化存储大小(播放“列俄罗斯方块”)并在数据页上挤压更多行 - 这是速度最重要的因素。
像this related answer这样的极端例子,你会得到很大的不同 通常情况下不值得打扰。
另一个因素是,如果首先使用固定大小的列,则检索列值会稍微快一些。我引用manual here:
要读取您需要依次检查每个属性的数据。第一 根据空位图检查字段是否为NULL。如果它 是,转到下一个。然后确保你有正确的对齐方式。如果 该字段是固定宽度字段,然后所有字节都是简单的 放置。如果它是一个可变长度字段(attlen = -1)那么它有点 更复杂。所有可变长度数据类型共享公共 头结构struct varlena,包括总长度 存储的值和一些标志位。
有一个开放的TODO item to allow reordering of column positions in the Postgres Wiki,部分是出于这些原因。
当postgres执行CREATE TABLE时,它遵循列顺序 指定或者以字节的最佳顺序重新组织列 对齐还是表现?
列以定义的顺序存储 ,系统不会尝试优化。
我没有看到列顺序与TOAST tables的任何相关性,就像另一个答案似乎暗示的那样。
答案 1 :(得分:3)
据我了解,PostgreSQL遵循保存记录时输入列的顺序。这是否会影响性能是值得商榷的。 PostgreSQL将所有表数据存储在每个大小为8kb的页面中。 8kb是默认值,但可以在编译时更改。
表格中的每一行都占用页面内的空间。由于表定义包含变量列,因此页面可以包含可变数量的记录。您要做的是确保您可以将尽可能多的记录放入一个页面。这就是为什么当表有大量列或列大小时会发现性能下降的原因。
这就是说,声明varchar(8192)并不意味着页面将填充一个记录,但声明CHAR(8192)将占用一整页而不管列中的数据量。 / p>
在声明TOASTable类型(如TEXT列)时还有一件事需要考虑。这些列可能超过最大页面大小。具有TOASTable列的表将具有关联的TOAST表来存储数据,并且只有指向数据的指针与表一起存储。这可能会影响性能,但可以使用TOASTable列上的适当索引进行改进。
总而言之,我不得不说列的顺序在表的性能中不起作用。大多数查询使用单独存储的索引来检索记录,因此列顺序被否定。它归结为需要读取多少页来检索数据。