postgres 综合性能

Posted

技术标签:

【中文标题】postgres 综合性能【英文标题】:postgres aggregate performance 【发布时间】:2012-02-15 05:13:40 【问题描述】:

我注意到 Postgres (8.3) 中的简单聚合性能存在一些问题。问题是,如果我有一个由 (customer_id,order_id) 唯一的表(比如 200M 行),那么查询 select customer_id,max(order_id) from larger_table group by customer_id 比执行以下操作的简单 Java/JDBC 程序慢一个数量级以上:

1) 初始化一个空的 HashMap customerMap(这将映射 id -> max order size) 2) 执行“select customer_id,order_id from large_table”,得到一个流式结果集 3) 遍历结果集,在每一行执行如下操作:

long id = resultSet.getLong("customer_id");
long order = resultSet.getLong("order_id");
if (!customerMap.containsKey(id)) 
    customerMap.put(id,order);
else 
    customerMap.put(id,Math.max(order,customerMap.get(id)));

这种性能差异是预期的吗?我不应该这么想,因为我想上面的内容非常接近内部发生的事情。是否有证据表明数据库存在错误/不正确的调整?

【问题讨论】:

请在您的声明中包含EXPLAIN ANALYZE 的输出,以便我们查看您是否缺少索引。 【参考方案1】:

可能是您的work_mem 设置太低。我会先检查一下。我最近被这个咬了。第二个最可能的问题是您缺少外键索引。

接下来是展览。

一般来说,当数据库性能看起来低于标准时,需要问几个问题:

    您使用的是最新版本吗? 7.4 和 9.0 之间的每个版本都带来了显着的性能改进 - 如果可以升级,建议升级。 您是否在真实数据上运行基准测试? PostgreSQL 的查询计划器将在同一张表上生成不同的计划,其中包含不同的数据或不同数量的数据。确保始终使用真实数据进行测试。 您的 PostgreSQL 配置是怎样的? work_mem 开箱即用的设置很低,我自己也遇到过涉及 GROUP BY 的情况,它人为地选择了错误的计划,因为它根本认为它没有足够的工作内存来对结果进行排序。李> 您的 Java 代码是否与数据库在同一台机器上运行?如果不是,您可能会看到计算机之间的差异,而不是方法之间的差异。 您是否缺少索引? PostgreSQL 不会自动为外键创建索引,只为主键创建索引。我也被这个咬过,但是如果你在周围搜索一下,你可以找到一个脚本来检测和添加丢失的外键索引。

在不检查查询计划的情况下,事后猜测 PostgreSQL 为给定查询选择了什么实施策略并不是一个好主意。

【讨论】:

work_mem 的附录:与 JVM 默认分配的内存相比,默认设置低得离谱。如果 Java 可以将所有 (customer,max_order_id) 元组保留在内存中,但 PostgreSQL 不能……那将是一场非常不公平的游戏。 ;-)

以上是关于postgres 综合性能的主要内容,如果未能解决你的问题,请参考以下文章

Postgres:使用游标更新的惊人性能

Postgres 分区性能调优

Postgres 表中列的顺序会影响性能吗?

提高 postgres 的性能

Postgres 中的性能问题 jsonb

提高 RODBC-Postgres 写入性能