2012-02-24 2 views
0

私はPostgres 9..0のクエリプランを変更する方法について詳しくは探しています。Postgres 9.0のクエリプランを変更する

私は、クエリがあります。

SELECT 
    max(creation_date) 
FROM 
    statistics_loged_users 
WHERE 
    school_id = 338 and 
    group_id  = 3 and 
    usr_id  = 243431; 

と出力を分析説明:

"Aggregate (cost=1518.56..1518.57 rows=1 width=8) (actual time=410.459..410.459 rows=1 loops=1)" 
" -> Bitmap Heap Scan on statistics_loged_users (cost=993.96..1518.55 rows=1 width=8) (actual time=410.025..410.406 rows=210 loops=1)" 
"  Recheck Cond: ((group_id = 3) AND (usr_id = 243431))" 
"  Filter: (school_id = 338)" 
"  -> BitmapAnd (cost=993.96..993.96 rows=133 width=0) (actual time=409.521..409.521 rows=0 loops=1)" 
"    -> Bitmap Index Scan on statistics_loged_users_idx2 (cost=0.00..496.85 rows=26669 width=0) (actual time=375.770..375.770 rows=3050697 loops=1)" 
"     Index Cond: (group_id = 3)" 
"    -> Bitmap Index Scan on statistics_loged_users_idx (cost=0.00..496.85 rows=26669 width=0) (actual time=0.077..0.077 rows=210 loops=1)" 
"     Index Cond: (usr_id = 243431)" 
"Total runtime: 411.419 ms" 

我々は最初のフィルタはgroup_idのことであることがわかりますが。 このテーブルは非常に非常に大きい:) group_idは同じですが、同じusr_idを持つ行はずっと少ない行がたくさんあります。

質問最初のフィルタがusr_idでなければならないということは、どのようにクエリプランに伝えることができますか。

私はgroup_idの上のインデックスとusr_idを作成し、私はパフォーマンスを持って、 私はクエリプランを変更する方法を知っておく必要があり、それは将来のためにあります:)

+0

推定行26,669、実際3,050,697。私は '真空分析'が順調だと思う。定期的にやっていますか? –

答えて

1

PostgreSQLプランナーは、実際にあなたが望む方法でヒントを受け入れていません。必要なものを達成する最も簡単な方法は、クエリを書き換えることです。 >ビットマップインデックススキャンstatistics_loged_users_idx2上(コスト= 0.00..496.85行= 26669幅= 0 -

」:

あなたEXPLAIN ANALYZE出力を分析し、それはほとんどの時間は、次のセクションで費やされていることは明らかです)(実際の時間= 375.770..375.770行= 3050697のループ= 1)」

"インデックスのCond:(GROUP_ID = 3)"

あなたは最初だけusr_idを探すためにクエリを書き換えた場合およびschool_idあなたはあなたが望むものを手に入れます。

SELECT 
    max(creation_date) 
FROM 
(
    SELECT 
     group_id, creation_date 
    FROM 
     statistics_loged_users 
    WHERE 
     school_id = 338 and 
     usr_id  = 243431 
) AS cd 
WHERE 
group_id = 3; 
1

現在のクエリは、現在2つのインデックスを使用する必要があり、statistics_loged_users_idxとstatistics_loged_users_idx2、1つのインデックスが高速になる可能性があります。 usr_id、group_id、およびschool_idに単一の索引を作成し、索引で他の列順序も試してください。

二つの例:

CREATE INDEX idx_triple_index ON statistics_loged_users(usr_id, group_id, school_id); 

CREATE INDEX idx_triple_2_index ON statistics_loged_users(usr_id, school_id, group_id); 

はそれを試してみると、再び、EXPLAIN ANALYZE確認してください。

+0

うん、これはトリックだ - より多くの性能を持っている:)しかしとにかく - クエリを実行する方法をいくつかのパラメータを設定することによって計画を変更する方法がある。たとえば、(各列にインデックスを付けて、単一のインデックスではなく)フィルタインデックスの順序を指定しますか? – marechs

関連する問題