4

Postgres (8.3) の単純な集計パフォーマンスに問題があることに気付きました。問題は、(customer_id,order_id) によって一意であるテーブル (たとえば 2 億行) がある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 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)));

このパフォーマンスの違いは予想されますか? 上記は内部で起こっていることにかなり近いと思うので、そうは思わないでください。データベースに何か問題がある/正しく調整されていないという証拠ですか?

4

1 に答える 1

6

おそらくwork_mem設定が低すぎるのでしょう。最初にそれを確認します。最近これにハマってます。2 番目に考えられる問題は、外部キー インデックスがないことです。

説明が続きます。

一般に、データベースのパフォーマンスが標準以下に見える場合は、いくつかの質問をする必要があります。

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

クエリ プランを調べずに、特定のクエリに対して PostgreSQL がどのような実装戦略を選択したかを推測するのは得策ではありません。

于 2012-02-15T05:26:05.217 に答える