2012-02-15 12 views
4

私はPostgres(8.3)の単純な集計パフォーマンスにいくつかの問題があることに気づいています。問題は、(customer_id、order_id)によって一意のテーブル(200M行)がある場合、クエリselect customer_id,max(order_id) from larger_table group by customer_idは、次のような単純なJava/JDBCプログラムよりも1桁以上遅いということです。postgres集計パフォーマンス

1)空のHashMapのcustomerMapを初期化する(id - > max order sizeをマップする) 2) "select customer_id、order_id from larger_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に調整されているという証拠ですか?

+3

あなたのステートメントに 'EXPLAIN ANALYZE'の出力を含めて、インデックスがないかどうかを確認してください。 –

答えて

6

おそらくwork_memの設定が低すぎます。私はまずそれをチェックしたいと思います。最近私はこれに噛まれてしまった。 2番目の可能性の高い問題は、外部キー索引がないことです。

博覧会が続きます。一般的に

、データベースのパフォーマンスは、サブパーに見えるたび尋ねする必要があるいくつかの質問があります。

  1. あなたは、最新のバージョンを使用していますか? 7.4と9.0の間のリリースでは、パフォーマンスが大幅に向上しました。アップグレードが可能な場合は、推奨されています。
  2. 現実的なデータでベンチマークを実行していますか? PostgreSQLのクエリプランナは、同じテーブル上で異なるデータまたは異なる量のデータを持つ異なるプランを生成します。現実的なデータで常にテストすることを確認してください。
  3. PostgreSQLの設定はどのようなものですか? work_memの設定はあまりにも早いですが、自分ではGROUP BYという状況に陥っています。人為的に間違った計画を選択していたのは、結果を並べ替えるのに十分な作業メモリがないと思ったからです。
  4. Javaデータベースと同じマシンで実行されているコードですか?そうでない場合、アプローチ間の違いではなく、コンピュータ間の違いを見ることができます。
  5. インデックスがありませんか? PostgreSQLは外部キーのためのインデックスを自動的には作成せず、主キーだけを作成します。私もこれに噛まれていますが、もしあなたがGoogleの周りにいれば、不足している外来キーのインデックスを検出して追加するスクリプトを見つけることができます。

クエリプランを調べていないと、PostgreSQLが特定のクエリに対してどのような実装方法を選択したかを推測することはお勧めできません。

+2

'work_mem'への補足事項:デフォルト設定は、JVMがデフォルトで割り当てるメモリに比べてばかげたものです。 Javaが '(customer、max_order_id)'のタプルをすべてメモリに残しても、PostgreSQLはそうでない場合、それはかなり不公正なゲームになります。 ;-) –

+2

仕事のmemは、犯人であることが判明しました!ありがとう – ryan