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

ibz*_*ibz 10 postgresql optimization performance

我有一个非常大的表(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调整一些参数到甚至移动到另一个数据库(我猜一个非关系数据库更适合这个特定的表,但我没有太多的经验).

Fra*_*ens 24

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

ALTER TABLE tablename SET (FILLFACTOR = 70);
VACUUM FULL tablename;
REINDEX TABLE tablename;
Run Code Online (Sandbox Code Playgroud)

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

  • 解决了这个问题.带来了我每天从9h到1h的整批4M更新.\ o /我做了类似于CLUSTER的事情,但手动.CLUSTER不仅锁定表,还使用了大量资源.所以我只是创建了另一个具有相同结构的表,并按照我想要的顺序插入记录(INSERT INTO ... SELECT FROM ... ORDER BY a,b,c)并确保我的UPDATE发生的顺序与现在在磁盘上的物理顺序(a,b,c).在解决这个问题时学到了很多东西.谢谢你们! (6认同)
  • 由于新版本的记录(由于更新)将被放置在不同的页面上,因此可能会降低性能.当你有很多记录时,你也会有很多页面.将新版本远离原始版本,将对查询计划产生影响.使用EXPLAIN查看会发生什么.还要考虑CLUSTER以与索引存储其信息相同的顺序存储记录.你必须使用fillfactor,更新的记录必须保持接近原始的记录. (3认同)