我的问题与Postgres如何运作有关:

我有一张 table :


CREATE TABLE A (
   id SERIAL,
   name VARCHAR(32),
   type VARCHAR(32) NOT NULL,
   priority SMALLINT NOT NULL,
   x SMALLINT NOT NULL,
   y SMALLINT NOT NULL,
   start timestamp with time zone,
   end timestamp with time zone,
   state Astate NOT NULL,
   other_table_id1 bigint REFERENCES W,
   other_table_id2 bigint NOT NULL REFERENCES S,
   PRIMARY KEY(id)
); 

在other_table_id1,state和other_table_id2上具有其他索引。

该表很大,在列上可以看到很多更新:other_table_id1,状态。开始和结束列进行了一些更新,但其余部分是不可变的。 (Astate是列状态的枚举类型。)

我想知道将两个最频繁更新的列拆分到一个单独的表中是否有意义。我希望获得的性能是性能,因为当我只是查找该信息时,或者为了减少更新的权重,因为(也许是?)读写较短行的成本较低。但是,我需要权衡一下(有时)需要同时拥有一个特定项目的所有数据的联接成本。

有一次,我的印象是每一列都是分开存储的。但是后来,当我读到某处内容时,我改变了想法,减少表格一侧的列宽度确实会对使用另一列查找数据时的性能产生积极影响(因为该行存储在一起,因此总行长会较短)。因此,我的印象是一行中的所有数据都物理存储在磁盘上。因此建议的拆分表听起来很有帮助。当我当前写入4个字节以更新状态时,我是否相信我正在重写实际上从未改变的64个字节的文本(名称,类型)?

我对表格“规范化”不是很有经验,也不了解Postgres的内部原理,因此我在寻找建议和esp最佳实践来评估折衷,而不必先进行工作,然后确定该工作是否值得。所做的更改将需要付出相当大的努力来重写已经高度优化的查询,因此我宁愿对我可以预期的结果有一个很好的了解。谢谢,M

最佳答案

更新较大的行有一定的成本。

公式可以帮助解决这个问题。如果不分割,您的费用为

成本= xU + yS

在哪里:

U =更新整行(不拆分表)

S =选择成本

x,y = Action 计数

然后,如果您将其拆分,则尝试计算出以下内容:

成本= gU1 + hU2 + xS1 + yS2

在哪里

U1 =更新较小的表(降低成本)

U2 =更新较大的表(降低成本)

S1 =从较小的表中选择

S2 =从较大的表中选择

g,h,x,y =个别 Action 发生的频率

因此,如果g >> h,则有必要将它们分解。特别是如果x >> y,那么它确实值得。

编辑:在回应评论时,我还要指出,如果数据库处于持续负载下且没有任何事件,则这些成本将变得更加重要。相反,如果服务器没有承受持续的负载,则它通常仅以每秒1或2 trx的速度处于不事件状态,并且长时间不事件(其中“long” =几秒钟)处于不事件状态,那么,如果是我,我就不会变得复杂我的代码,因为性能优势不会真正体现出来。

关于sql - Postgres : one table with many columns or several tables with fewer columns?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4878543/

10-16 15:21