2012-03-13 19 views
1

私はテーブルを持っています。 各ループには、約36k行が挿入されます。ポストグルでのパフォーマンスが極端に遅い

このテーブルからperfom操作まで行を取得する必要があります。 問題は、すべてのループでクエリのパフォーマンスが本当に悪いです。

例えば、ループ31上:ループ43

explain analyze select exp(least(709,a.value)), a.from, a.to,a.material,a.transport from resultTable a where a.loop=31; 
                      QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on resultTable a (cost=36.58..4431.79 rows=2425 width=48) (actual time=7.351..33894.217 rows=34640 loops=1) 
    Recheck Cond: (loop = 31) 
    -> Bitmap Index Scan on "resultTable_idx_mo" (cost=0.00..35.97 rows=2425 width=0) (actual time=4.880..4.880 rows=34640 loops=1) 
     Index Cond: (loop = 31) 
Total runtime: 33897.070 ms 
(5 rows) 

explain analyze select exp(least(709,a.value)), a.from, a.to,a.material,a.transport from resultTable a where a.loop=43; 
                      QUERY PLAN 
----------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Bitmap Heap Scan on resultTable a (cost=36.58..4431.79 rows=2425 width=48) (actual time=10.129..125460.445 rows=34640 loops=1) 
    Recheck Cond: (loop = 43) 
    -> Bitmap Index Scan on "resultTable_idx_mo" (cost=0.00..35.97 rows=2425 width=0) (actual time=4.618..4.618 rows=34640 loops=1) 
     Index Cond: (loop 43) 
Total runtime: 125463.516 ms 
(5 rows) 

時間として指数関数的に成長しています。 私はすべてのループでVACUUMとREINDEXを実行しています(私も試しましたが、結果は同じです)。

時間を改善する方法はありますか?

ありがとうございます。パーティション後

QUERY PLAN 
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Result (cost=14.47..2686.29 rows=1649 width=48) (actual time=18.562..220124.597 rows=34640 loops=1) 
    -> Append (cost=14.47..2682.17 rows=1649 width=48) (actual time=5.189..32.743 rows=34640 loops=1) 
     -> Bitmap Heap Scan on resultTable a (cost=14.47..1655.44 rows=866 width=48) (actual time=0.008..0.008 rows=0 loops=1) 
       Recheck Cond: (loop = 60) 
       -> Bitmap Index Scan on "resultTable_idx_mo" (cost=0.00..14.26 rows=866 width=0) (actual time=0.006..0.006 rows=0 loops=1) 
        Index Cond: (loop = 60) 
     -> Bitmap Heap Scan on result_table_child_70 a (cost=8.82..1026.73 rows=783 width=48) (actual time=5.181..29.068 rows=34640 loops=1) 
       Recheck Cond: (loop = 60) 
       -> Bitmap Index Scan on resultTable_child_70_idx (cost=0.00..8.63 rows=783 width=0) (actual time=4.843..4.843 rows=34640 loops=1) 
        Index Cond: (loop = 60) 
Total runtime: 220128.290 ms 

は後に表を分析し、設定enable_bitmapscan =オフ(まだ使用してパーティショニング):

Result (cost=0.00..2761.06 rows=33652 width=389) (actual time=9.714..378389.177 rows=34640 loops=1) 
    -> Append (cost=0.00..2676.93 rows=33652 width=389) (actual time=0.119..34.065 rows=34640 loops=1) 
     -> Index Scan using "resultTable_idx_mo" on resultTable a (cost=0.00..12.84 rows=5 width=48) (actual time=0.058..0.058 rows=0 loops=1) 
       Index Cond: (loop= 79) 
     -> Index Scan using resultTable_child_80_idx on resultTable_child_80 a (cost=0.00..2664.10 rows=33647 width=389) (actual time=0.061..30.303 rows=34640 loops=1) 
       Index Cond: (loop = 79) 
Total runtime: 378393.671 ms 
(7 rows) 

答えて

2

クラスタは、おそらくそれをスピードアップ:

cluster resultTable using resultTable_idx_mo; 

しかし、決定的な解決策は、ループでテーブルを分割することです:

http://www.postgresql.org/docs/current/interactive/ddl-partitioning.html

+0

'cluster'の後に' analyze'を発行しましたか? –

+0

@barbosoパーティションの後に説明を表示します。 –

4

クラスタリングとパーティションが動作しない場合は、私はあなたのストレージ・システムといくつかの深刻な問題を持っている疑い始めます。スキャンの35K行をヒープするための10秒間は、数桁のオーダーが遅すぎます。どのバージョンのPostgresを使用していますか?あなたのストレージはどのように見えますか?あなたのiostatsを確認してください。

テーブルとインデックスを作成し、それぞれ36000レコードの1000バッチを注入するPg 9.0.4の小さなVM(1つのフラクショナルCPU、1GB mem、NFSディスクマウント)で実験をセットアップしました。任意のバッチであなたの選択を実行

insert into r(loop,value,xfrom,xto,material,transport,pk) select 0,0,0,0,0,0,i from generate_series(0,35999) i; 
insert into r(loop,value,xfrom,xto,material,transport,pk) select 1,0,0,0,0,0,i from generate_series(36000,71999) i; 
... 

が40msの下に一貫している:

explain analyze select exp(least(709,a.value)), a.xfrom, a.xto, a.material,a.transport from r a where a.loop=31; 
Index Scan using "resultTable_idx_mo" on r a (cost=0.00..1596.35 rows=37680 width=21) (actual time=0.087..34.038 rows=36000 loops=1) 
    Index Cond: (loop = 31) 
Total runtime: 36.332 ms 

explain analyze select exp(least(709,a.value)), a.xfrom, a.xto,a.material,a.transport from r a where a.loop=87; 
Index Scan using "resultTable_idx_mo" on r a (cost=0.00..1421.35 rows=33480 width=21) (actual time=0.105..37.357 rows=36000 loops=1) 
    Index Cond: (loop = 87) 
Total runtime: 39.365 ms 

私の計画に注意してください。代わりにHeapScans続いBitmapScansの通常INDEXSCANのを思い付きます。計画に影響を与えるプラン最適化設定で調整しましたか?

あなたの説明では、推定ローカウントが実際のローカウント(1649 vs 34640)よりはるかに小さいことに注意してください。これは、テーブルの統計が不正確であることを示します。あなたが実行する必要がありますANAYLZE resultTable;

私はこれらの単純なインデックスのスキャンの選択が数十ミリ秒以上かかる場合は、あなたのポストグル設定またはストレージシステムでひどいものがあったと信じています。クエリを実行するときにこのデータベースに他のアクティビティがありますか?おそらくあなたの結果は、他のクエリとリソースの競合ですか?

+0

私は(ループ79を使って)一番下のポストを更新しました。ありがとう – baboso

+0

同じループ値で2回連続してExplain分析を実行すると、ランタイムが大幅に向上しますか? 36K * 48バイトの行幅は約2MBです。 pgがすべてのデータブロックを読み込んだら、簡単に収まるようにして、適切なサイズのシステム上でOSページキャッシュに保持する必要があります.2回目の実行では、ヒープスキャンはI/Oなしでメモリから完全に行を収集する必要があります。あなたのシステムにはどれくらいのメモリがありますか? – dbenhur

関連する問題