Optimization 绩效优化-研究生

Optimization 绩效优化-研究生,optimization,postgresql,performance,Optimization,Postgresql,Performance,我的任务是改进一个缓慢运行的进程的性能,该进程更新PostGres 8.3数据库中的一些数据(在Solaris上运行,更新由通过SOAP的Perl 5.8脚本驱动)。大约50%的时间我几乎无法控制,因此调整我的50%是非常重要的 表中通常有大约4500000行,尽管我已经看到它膨胀到大约7000000行。更新所查询的id(不是主id或唯一id)的不同值略低于9000个,并且每个id的事件分布权重很大(中值为20,最大值为7000) 这个id上有一个索引,但由于数据如此稀疏,我想知道是否有更好的方

我的任务是改进一个缓慢运行的进程的性能,该进程更新PostGres 8.3数据库中的一些数据(在Solaris上运行,更新由通过SOAP的Perl 5.8脚本驱动)。大约50%的时间我几乎无法控制,因此调整我的50%是非常重要的

表中通常有大约4500000行,尽管我已经看到它膨胀到大约7000000行。更新所查询的id(不是主id或唯一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;
UPDATE tab1 SET client='abcd',invoice=999
其中id='A100062'和发布时间<'02-11-09'::日期
费用不为空,发票为空,客户为空;
我意识到“不为空”远非理想。Id和invoice&client(b树,因此我理解PostGres将/应该/可以在那里使用索引)一样被索引。这是一个非常简单的查询

查询计划(用分析说明):

选项卡1上的位图堆扫描(成本=17.42..1760.21行=133宽度=670)(实际时间=0.603..0.603行=0循环=1) 复查条件:((id)::text='A100062'::text)和(发票为空)) 筛选器:((费用不为空)和(客户端为空)和(发布时间<'2009-11-02'::日期)) ->cdr_快照_2007_09_12_snbs_发票上的位图索引扫描(成本=0.00..17.39行=450宽度=0)(实际时间=0.089..0.089行=63圈=1) 索引条件:((SNB)::text='A100062'::text)和(发票为空)) 总运行时间:0.674毫秒 我相信,自动真空系统已启用。这里没有外键限制,但是谢谢你的提示,因为我不知道


我真的很喜欢增加统计值的想法——我马上就要玩这个了。

你真的需要得到一些查询计划,并编辑你的问题以包含它们。除了帮助找出更好的做事方法外,它们还可以用来轻松衡量改进情况


您可以通过更改SQL或调整用于确定查询计划的索引和统计信息来影响性能


一种可能性是,您的外键约束没有支持索引。创建外键约束时,PostgreSQL不会自动添加它们。如果引用表中删除了一行(或更新了引用字段),则需要完全扫描引用表,以级联删除,或确保没有行引用已删除的行


如果id字段的分布非常倾斜,增加该列的统计信息可能会有所帮助

如果统计设置为100,则将记录100个最常见的ID(来自样本)及其频率。假设它覆盖了大约50%的表,剩下2到350万行,PostgreSQL将假定这些行与其他8900个ID平均分布, 或者每次大约250到400次

如果统计数据增加到1000,并且前1000个ID覆盖了95%的行,PostgreSQL将假定不在1000个最常见的ID列表中的ID将出现30到40次

估计值的更改可能会影响所选的查询计划。如果查询模式更频繁地选择查找频率较低的ID,则PostgreSQL将高估找到这些ID的次数


存储这么多最频繁的值会带来性能成本,因此您确实需要支持查询计划分析来确定是否获得净收益。

您确实需要获取一些查询计划,并编辑问题以将其包括在内。除了帮助找出更好的做事方法外,它们还可以用来轻松衡量改进情况


您可以通过更改SQL或调整用于确定查询计划的索引和统计信息来影响性能


一种可能性是,您的外键约束没有支持索引。创建外键约束时,PostgreSQL不会自动添加它们。如果引用表中删除了一行(或更新了引用字段),则需要完全扫描引用表,以级联删除,或确保没有行引用已删除的行


如果id字段的分布非常倾斜,增加该列的统计信息可能会有所帮助

如果统计设置为100,则将记录100个最常见的ID(来自样本)及其频率。假设它覆盖了大约50%的表,剩下2到350万行,PostgreSQL将假定这些行与其他8900个ID平均分布, 或者每次大约250到400次

如果统计数据增加到1000,并且前1000个ID覆盖了95%的行,PostgreSQL将假定不在1000个最常见的ID列表中的ID将出现30到40次

估计值的更改可能会影响所选的查询计划。如果查询模式更经常选择
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