postgres聚合性能

时间:2012-02-15 05:13:40

标签: sql performance postgresql database-tuning aggregates

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

1)初始化一个空的HashMap customerMap(这将映射id - >最大订单大小) 2)执行“select_ customer_id,order_id from greater_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)));

预计会有这种性能差异吗?我不应该想,因为我认为上面的内容与内部发生的情况非常接近。是否证明db有错误/错误调整?

1 个答案:

答案 0 :(得分:6)

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

博览会如下。

通常,只要数据库性能看起来低于标准,就需要提出几个问题:

  1. 您使用的是最新版本吗? 7.4和9.0之间的每个点发布都带来了显着的性能改进 - 如果可以升级,建议使用。
  2. 您是否在实际数据上运行基准测试? PostgreSQL的查询规划器将在同一个表上生成不同的计划,其中包含不同的数据或不同数量的数据。确保始终使用实际数据进行测试。
  3. 你的PostgreSQL配置是什么样的? work_mem设置开箱即用,我自己遇到了涉及GROUP BY的情况,人为地选择了错误的计划,因为它根本不认为它有足够的工作记忆来对结果进行排序英寸
  4. 您的Java代码是否与数据库在同一台机器上运行?如果没有,您可能会看到计算机之间的差异,而不是方法之间的差异。
  5. 你错过了一个索引吗? PostgreSQL不会为外键自动创建索引,只是主键。我也被这个咬了,但是如果你在google周围找到一个可以检测并添加丢失的外键索引的脚本。
  6. 在不检查查询计划的情况下,猜测PostgreSQL为给定查询选择的实现策略并不是一个好主意。