我的任务是提高缓慢运行进程的性能,该进程更新PostGres 8.3数据库(在Solaris上运行,更新由Perl 5.8脚本通过SOAP驱动)中的一些数据。大约50%的时间消耗我很少控制,所以调整我的50%是非常重要的。性能优化 - Postgres
表中通常有大约4,500,000行,尽管我已经看到它膨胀到约700万。更新查询的ID(不是主要的或唯一的)具有近9000个不同的值,并且事件的传播对每个ID大量加权(中值为20,最大值为7000)。
这个ID有一个索引,但有这样稀疏的数据我不知道是否有更好的方法做事情。我也在考虑对数据进行非规范化处理(无论如何,数据库并没有超标准化)&将数据拉出到单独的表格中(可能由触发器控制/维护)以帮助加快速度。
到目前为止,我已经做了一些非常基本的调整(不是每n秒钟ping数据库以查看它是否存在,不会不必要地设置会话变量等),这是有帮助的,但我真的觉得有些东西我缺少与数据...
即使有人说,拉出相关数据到一个单独的表是一个很好的/可怕的想法,这将是非常有益的!任何其他想法(或进一步的澄清问题)感激地收到!
查询:
UPDATE tab1 SET client = 'abcd', invoice = 999
WHERE id = 'A1000062' and releasetime < '02-11-09'::DATE
AND charge IS NOT NULL AND invoice IS NULL AND client IS NULL;
我意识到 '不为空' 是远远不够理想。编号索引,发票&客户端(btrees,所以我明白PostGres将/应该/可以使用索引那里)。这是一个很琐碎的查询......
查询计划(与分析讲解):
Bitmap Heap Scan on tab1 (cost=17.42..1760.21 rows=133 width=670) (actual time=0.603..0.603 rows=0 loops=1)
Recheck Cond: (((id)::text = 'A1000062'::text) AND (invoice IS NULL))
Filter: ((charge IS NOT NULL) AND (client IS NULL) AND (releasetime < '2009-11-02'::date))
-> Bitmap Index Scan on cdr_snapshot_2007_09_12_snbs_invoice (cost=0.00..17.39 rows=450 width=0) (actual time=0.089..0.089 rows=63 loops=1)
Index Cond: (((snbs)::text = 'A1000062'::text) AND (invoice IS NULL))
Total runtime: 0.674 ms
自动清理的,我相信,启用。没有外键约束,但感谢提示,因为我不知道这一点。
我真的很喜欢增加统计值的想法 - 我马上就会玩一玩。
查询计划是什么样子的,您是否启用了autovacuum或是否定期执行真空(不运行autovacuum)。 – 2009-11-03 08:10:31