代码之家  ›  专栏  ›  技术社区  ›  azp74

性能优化-Postgres

  •  0
  • azp74  · 技术社区  · 16 年前

    我的任务是改进运行缓慢的进程的性能,该进程更新Postgres8.3数据库中的一些数据(在Solaris上运行,更新由通过SOAP的Perl5.8脚本驱动)。大约50%的时间消耗我几乎没有控制,所以调整我的50%是非常重要的。

    表中通常有大约4500000行,尽管我已经看到它膨胀到大约7000000行。更新查询的ID(不是主ID或唯一ID)的不同值略低于9000,并且出现次数的分布严重加权为每个ID 1(中值为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;
    

    我意识到“不是空的”离理想还很远。ID的索引与发票和客户机一样(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
    

    我相信自动真空是可以实现的。没有外键限制,但谢谢您的提示,因为我不知道这一点。

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

    1 回复  |  直到 16 年前
        1
  •  0
  •   Stephen Denne    16 年前

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


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


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


    如果您的ID字段的分布非常不稳定,那么增加该列的统计信息可能会有所帮助。

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

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

    估计值的更改会影响所选的查询计划。如果查询模式更频繁地选择ID,那么PostgreSQL将高估找到ID的次数。

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