PostgreSQL在一个包含数组和大量更新的大型表上变慢

时间:2010-06-23 08:32:26

标签: performance optimization postgresql

我有一个非常大的表(20M记录),它有一个3列索引和一个数组列。数组列每天更新(通过附加新值)所有行。还有插入,但没有更新。

数组中的数据表示与三个键对应的每日测量值,如下所示:[[date_id_1, my_value_for_date_1], [date_id_2, my_value_for_date_2]]。它用于绘制这些每日值的图表。假设我希望随着时间的推移可视化密钥(a,b,c)的值,我会SELECT values FROM t WHERE a = my_a AND b = my_b AND c = my_c。然后我使用values数组绘制图形。

更新的性能(每天大量发生一次)随着时间的推移而显着恶化。

使用PostgreSQL 8.3.8。

您能给我一些关于在哪里寻找解决方案的提示吗?它可能是从postgres调整一些参数到甚至移动到另一个数据库(我猜一个非关系型数据库更适合这个特定的表,但我没有太多经验)。

4 个答案:

答案 0 :(得分:22)

我会看看桌子上的FILLFACTOR。默认情况下,它设置为100,您可以将其降低到70(开始时)。在此之后,您必须执行VACUUM FULL来重建表。

ALTER TABLE tablename SET (FILLFACTOR = 70);
VACUUM FULL tablename;
REINDEX TABLE tablename;

这使UPDATE有机会将行的更新副本放在与原始页面相同的页面上,这比将其放在不同页面上更有效。或者,如果您的数据库已经从之前的许多更新中分散了一些,那么它可能已经足够了。现在,您的数据库还可以选择执行HOT updates,假设您要更新的列不是任何索引中涉及的列。

答案 1 :(得分:2)

不确定是否可以使用数组。

为什么不将它们存储在一个单独的表中(每行一个值加上键) 那么批量更新将是纯插入活动。

答案 2 :(得分:2)

问题在于更新。将架构从基于每天的多行更改为多行,性能问题将消失。

您可以稍后使用某种cronjob向数组添加汇总,但请避免更新。

答案 3 :(得分:1)

3柱索引无需担心。这并不一定会让它慢得多。但是那个阵列列确实可能是问题所在。您说您每天都会将值附加到该数组列。通过附加,你的意思是为所有20万的增值附加值。表中的记录?或者只是一些记录?

这种情况对我来说并不完全清楚,但我会建议寻找摆脱阵列列的方法。例如,将它作为一个单独的表。但是,这取决于您的情况,可能不是一种选择。 它可能只是我,但我总觉得“脏”在我的一张桌子上有这样一个列。大多数情况下,对于您尝试使用该阵列列解决的问题,有一个更好的解决方案。话虽这么说,有一些情况下这样的专栏是有效的,但目前,我认为没有。当然不在一张20毫升的桌子里。记录计数。