1

パフォーマンスを改善するために、パラメータ shared_buffers と work_mem を調整しました。上記のパラメーターのさまざまな組み合わせを試しましたが、クエリに同じ時間がかかりました。「shared_buffer」が変更されるたびにサーバーを再起動しました私の環境は

Postgres 9.1 OS Windows 7 RAM 8GB

1gb、2gb、3gb の shared_buffers を試しました。ただし、クエリの実行時間の変化はごくわずかです(ミリ秒単位)

クエリの説明プランを提供しています

GroupAggregate  (cost=11100.99..12737.10 rows=50342 width=24) (actual time=181.789..268.733 rows=49829 loops=1)
  ->  Sort  (cost=11100.99..11226.84 rows=50342 width=24) (actual time=181.761..188.323 rows=50000 loops=1)    
        Sort Key: (date(t_proof_of_play.play_timestamp)), (date_trunc(''hour''::text, t_proof_of_play.play_timestamp)), t_device_endpoint.venue_hierarchy_id, t_device_endpoint.device_config_id, t_proof_of_play.asset_id
        Sort Method: quicksort  Memory: 5443kB
        ->  Hash Join  (cost=2629.37..7169.41 rows=50342 width=24) (actual time=15.416..112.175 rows=50000 loops=1)
              Hash Cond: (t_proof_of_play.device_endpoint_id = t_device_endpoint.id)
              ->  Bitmap Heap Scan on t_proof_of_play  (cost=2628.28..6224.41 rows=50342 width=20) (actual time=15.332..29.004 rows=50000 loops=1
                    Recheck Cond: ((is_processed = 0) AND (is_revenue = 1))
                    -> Bitmap Index Scan on process_revenue  (cost=0.00..2615.69 rows=50342 width=0) (actual time=15.081..15.081 rows=50000 loops=1)
                          Index Cond: ((is_processed = 0) AND (is_revenue = 1))
              ->   Hash  (cost=1.04..1.04 rows=4 width=12) (actual time=0.026..0.026 rows=4 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 1kB
                    ->  Seq Scan on t_device_endpoint  (cost=0.00..1.04 rows=4 width=12) (actual time=0.009..0.015 rows=4 loops=1)
Total runtime: 276.027 ms

Explain.depesz の表形式のバージョン

提案を歓迎します。前もって感謝します

よろしく

4

3 に答える 3

2

生の EXPLAIN から重要な数値を選択するのは難しい場合があります。幸いなことに、コミュニティの長年のメンバーが、それを集計するための便利なツールを作成してくれました。depesz.com へのリンクを追加しました。

まず、shared_buffers を変更すると、特定のクエリにどのような影響があるかわかりません。いずれにせよ、値を指定しませんでした。マシンのメモリ使用量の全体的なバランスを変更するのは一般的な値です。特定のクエリではなく、全体的なワークロードに基づいて調整します。

クエリの 3 つの主要な部分は、結合、並べ替え、および集計です。それは理にかなっているようです。

実行している集計がわかりません (クエリを指定していません)。おそらく、(ソートに基づいて) play_timestamp で日/時間にわたって要約しています。両方のレベルが必要ですか?

かなり詳細な並べ替え (5 列、関数呼び出しに基づく 2 つ)work_memの場合、並べ替えに十分な大きさである限り、何もする必要はありません。

そのため、結合を改善できる可能性があります。部分索引が役立つ可能性があります。何かのようなもの:

CREATE INDEX idx1 ON t_proof_of_play (device_endpoint_id) WHERE is_processed=0 AND is_revenue=1

もちろん、何も無料ではなく、更新するたびにこのインデックスの維持費を支払うことになりますt_proof_of_play

それでも、参加時間を半分にすると、全体の時間が 276 ミリ秒から約 235 ミリ秒に短縮されます。約 0.25 秒で 50,000 行を処理しています。つまり、1 行あたり 5 マイクロ秒です。

于 2013-10-15T09:09:47.870 に答える
1

@Richard Huxtonの回答を補足します。

Windowsのドキュメントに記載されているように、非常に大量のshared_buffersを使用することはできません。

また、Windows では、shared_buffers の大きな値は効果的ではありません。設定を比較的低く保ち、代わりにオペレーティング システムのキャッシュをより多く使用すると、より良い結果が得られる場合があります。Windows システムでの shared_buffers の有用な範囲は、一般に 64MB から 512MB です。

したがって、このパラメータを 512MB に設定する必要があります。PostgreSQL は、Windows でより多くの共有メモリを使用してメモリ使用を最適化できません。私の考えでは、Windows は PostgreSQL サーバーに最適な OS ではありません。とにかくeffective_cache_size、使用可能なメモリの 50% または 75% に微調整することもできます (おそらく 2 または 4GB のようなものです)。これは PostgreSQL のヒントであり、OS が利用可能な RAM を使用して最近使用したファイルを保存することを示しています。このようにして、クエリ オプティマイザは、ディスク データへのアクセスが通常考えられるほどコストがかからないと判断する可能性があります。

于 2013-10-15T11:50:44.493 に答える