2012-04-13 5 views
1

残念なことに、生産中(90列のテーブルの3つのmilionレコード)で約2分でクエリ(2つの条件で選択/結合)が実行される大きなPostgreSQLプロジェクトに取り組んでいます。postgresqlの最適化

クエリに最適化するものがないとすると、実行速度を上げるために変更できる設定はありますか? これは、データベースの設定です、と私は私のニーズに合ったものを見当がつかない:

version PostgreSQL 8.4.4 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44), 32-bit 
checkpoint_completion_target 0.9 
checkpoint_segments 10 
custom_variable_classes pg_stat_statements 
effective_cache_size 1GB 
lc_collate fr_FR.UTF-8 
lc_ctype fr_FR.UTF-8 
listen_addresses * 
log_autovacuum_min_duration 0 
log_line_prefix %t [%p]: [%l-1] user=%u,db=%d 
log_min_duration_statement 30s 
logging_collector on 
maintenance_work_mem 128MB 
max_connections 100 
max_stack_depth 2MB 
pg_stat_statements.max 1000 
pg_stat_statements.save on 
pg_stat_statements.track all 
random_page_cost 1.5 
server_encoding UTF8 
shared_buffers 128MB 
TimeZone Europe/Paris 
track_functions pl 
wal_buffers 1MB 
work_mem 8MB 

問合せ:

SELECT distinct 
    ((Table_Commande_Historique.COD_STECIAL 
    || ',' || Table_Commande_Historique.COD_MCIAL 
    || ',' || Table_Commande_Historique.NUM_REC_CLI 
    || ',' || Table_Commande_Historique.NUM_DNT_CLI 
    || ',' || Table_Commande_Historique.NUM_DDE)) cle 
FROM G1DDE2_DDE Table_Commande_Historique 
inner join "K2VER2_VER" ver 
    on (Table_Commande_Historique.NUM_REC_CLI 
     = (string_to_array(ver.num_cle,','))[3]::int 
    OR Table_Commande_Historique.NUM_DNT_CLI 
     = (string_to_array(ver.num_cle,','))[3]::int 
    OR ver.num_cle = (Table_Commande_Historique.COD_MCIAL 
        || ',' || Table_Commande_Historique.NUM_REC_CLI) 
    OR ver.num_cle = (Table_Commande_Historique.COD_MCIAL 
        || ',' || Table_Commande_Historique.NUM_DNT_CLI)); 

インデックス:

CREATE INDEX idx_combo1 
    ON g1dde2_dde 
    USING btree 
    (((cod_mcial || ','::text) || num_rec_cli)); 

    CREATE INDEX idx_combo2 
    ON g1dde2_dde 
    USING btree 
    (((cod_mcial || ','::text) || num_dnt_cli)); 

    CREATE INDEX idx_dnt 
    ON g1dde2_dde 
    USING btree 
    (num_dnt_cli); 

    CREATE INDEX idx_rec 
    ON g1dde2_dde 
    USING btree 
    (num_rec_cli); 

    CREATE INDEX idx_k2ver3sb 
    ON "K2VER2_VER" 
    USING btree 
    (num_cle); 

はEXPLAIN:

"HashAggregate (cost=197.97..201.77 rows=69 width=29)" 
" -> Nested Loop (cost=1.29..197.35 rows=248 width=29)" 
"  -> Seq Scan on "K2VER2_VER" ver (cost=0.00..2.58 rows=58 width=19)" 
"  -> Bitmap Heap Scan on g1dde2_dde table_commande_historique (cost=1.29..2.84 rows=5 width=29)" 
"    Recheck Cond: ((table_commande_historique.num_rec_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer) OR (table_commande_historique.num_dnt_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer) OR ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_rec_cli)::text)) OR ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_dnt_cli)::text)))" 
"    -> BitmapOr (cost=1.29..1.29 rows=5 width=0)" 
"     -> Bitmap Index Scan on idx_rec (cost=0.00..0.32 rows=2 width=0)" 
"       Index Cond: (table_commande_historique.num_rec_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer)" 
"     -> Bitmap Index Scan on idx_dnt (cost=0.00..0.32 rows=1 width=0)" 
"       Index Cond: (table_commande_historique.num_dnt_cli = ((string_to_array((ver.num_cle)::text, ','::text))[3])::integer)" 
"     -> Bitmap Index Scan on idx_combo1 (cost=0.00..0.32 rows=1 width=0)" 
"       Index Cond: ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_rec_cli)::text))" 
"     -> Bitmap Index Scan on idx_combo2 (cost=0.00..0.32 rows=1 width=0)" 
"       Index Cond: ((ver.num_cle)::text = (((table_commande_historique.cod_mcial)::text || ','::text) || (table_commande_historique.num_dnt_cli)::text))" 
+1

あなたのクエリ、テーブル、およびインデックスを表示します。 –

+1

説明を表示...または推測する必要がありますか? –

+0

OKですので、見栄えが悪いです。行数はかなり少ないです。クエリーに時間がかかりすぎるデータベースからの説明ですか? –

答えて

3
version PostgreSQL 8.4.4 

これは問題です。これを読んで、セキュリティの脆弱性やバグの修正を取得するためにマイナーリリースを検討してください:

http://www.postgresql.org/support/versioning/

これら時々は、パフォーマンス上の問題を引き起こすバグが含まれています。あなたが得るだろうか修正確認するには、あなたはここで8.4.5 8.4.11への注意事項になります:

http://www.postgresql.org/docs/8.4/static/release.html

RAMベースの設定のいくつかは、おそらくあまりにも低いですが、どのくらいのRAMを知らなくても、システム上にあり、そこには何が実行されているのか、特定の番号を提案する方法はありません。

shared_buffers 128MB 

Linux上で専用データベース・サーバのための通常のアドバイスは多分8ギガバイトの最大で、システム上の合計RAMの25%に設定して、ベンチマークに基づいて、そこから調整することです。

effective_cache_size 1GB 

これは、任意のRAMを割り当てますが、繰り返しコストのプランナーが、それはまだ同じクエリ内の以前の読み取りから、キャッシュ内にあることをどのように可能性の推定値に基づいて、ファイルから読み込むことができますしません。 shared_buffersのサイズを、OSがキャッシュとして表示するものに追加することをお勧めします。

work_mem 8MB 

この1つはトリッキーです。これは実際にさまざまな方法でパフォーマンスを照会するのに役立ちますが、値が高いとキャッシュから物を押し出してディスクアクセスを増やす傾向があります。また、各クエリーが(クエリーステップごとに)このような多くのスペースを何度か割り当てることができることを考慮する必要があるため、通常、許可される接続ごとにこのサイズを1回割り当てる必要があります。これはの1つで、多数のユーザーを限られた数の実際のデータベース接続に繋ぐために接続プールを使用することは、しばしば有益です。より大きなサイズのものがあれば、ビットマップ索引のスキャンが「損失」にならないようにし、索引条件を再確認する必要があるため、この問合せの助けとなる可能性が非常に高いです。

cpu_tuple_costは設定していませんが、通常はデフォルト設定が全体的に最適な計画を立てるには低すぎます。大きなテーブルに90個のカラムがあるとすれば、これを0.01から0.05に増やすことをお勧めします。

effective_io_concurrencyは設定されていませんが、それが役立つ可能性があります。私は異なる値でテストします。 (代替案の性能を比較するテストを実行している場合もちろん、キャッシュの問題について注意してください。)

maintenance_work_mem 128MB 

あなたが持っているどのくらいのRAMに応じて、これはあるいは合理的であってもなくてもよいです。あなたの直面する問題には影響しませんが、それを増やすことで自動バキュームがより効率的に実行され、インデックスビルドの実行速度が向上します。

これらは、おそらく少し低いです:

checkpoint_segments 10 
wal_buffers 1MB 

彼らはあなたの当面の問題の一部ではありませんが、彼らは余分なディスクが倍に書き込み、それはおそらく、それらを調整するために支払うことになる恐れがあります。 wal_buffersは、マシンのRAMが非常に限られている場合を除き、通常32MBです。 checkpoint_segmentsはそれ以上のことを知らなくても見積もりが難しいですが、ログと統計情報をチェックしてチェックポイントが頻繁に発生している場合は、checkpoint_timeoutに基づいてチェックポイントが発生するまでこのチェックポイントを増やすことをお勧めします。

+0

'shared_buffers'に' effective_io_concurrency'と正しいタイプミスを追加するように編集しました。 – kgrittn

+0

それは私が必要なものです!私は木曜日に結果を戻します。私は今休暇中です。どうもありがとう – Samson

関連する問題