私はマスター/ディテールテーブルの状況があります。マスターテーブルのすべてのエントリについて、私はディテールテーブルで数十を持っています。patial第2テーブルのデータを基にしたインデックス
これらは私のテーブルであると言うことができます:
+-----------------------
| Master
+-----------------------
| master_key integer,
| insert_date timestamp
+-----------------------
+-----------------------
| Detail
+-----------------------
| detail_key integer,
| master_key integer
| quantity numeric
| amount numeric
+-----------------------
そして、私の最も使用されるクエリは
SELECT extract(year from insert_date) AS Insert_Year, extract(month from insert_date) AS Insert_Month, sum(quantity) AS Quantity, sum(amount) AS Amount
FROM Master, Detail
WHERE (amount not null) and (insert_date <= '2016-12-31') and (insert_date >= '2015-01-01') and (Detail.master_key=Master.master_key)
GROUP BY Insert_Year, Insert_Month
ORDER BY Insert_Year ASC, Insert_Month ASC;
のようなものである。このクエリは、長年のデータのトンが両方のテーブルに存在するため、減速するなり、 。原因
私は両方のテーブルにインデックスを持っているとEXPLAIN ANALYZE
はINDEXスキャンが穴の実行時間の80%以上のモードを取ることを私に伝えます。
"Sort (cost=44013.52..44013.53 rows=1 width=19) (actual time=17073.129..17073.129 rows=16 loops=1)"
" Sort Key: (date_part('year'::text, master.insert_date)), (date_part('month'::text, master.insert_date))"
" Sort Method: quicksort Memory: 26kB"
" -> HashAggregate (cost=44013.49..44013.51 rows=1 width=19) (actual time=17073.046..17073.053 rows=16 loops=1)"
" Group Key: date_part('year'::text, master.insert_date), date_part('month'::text, master.insert_date)"
" -> Nested Loop (cost=0.43..43860.32 rows=15317 width=19) (actual time=0.056..15951.178 rows=843647 loops=1)"
" -> Seq Scan on master (cost=0.00..18881.38 rows=3127 width=12) (actual time=0.027..636.202 rows=182338 loops=1)"
" Filter: ((date(insert_date) >= '2015-01-01'::date) AND (date(insert_date) <= '2016-12-31'::date))"
" Rows Removed by Filter: 443031"
" -> Index Scan using idx_detail_master_key on detail (cost=0.43..7.89 rows=7 width=15) (actual time=0.055..0.077 rows=5 loops=182338)"
" Index Cond: (master_key = master.master_key)"
" Filter: (amount IS NOT NULL)"
" Rows Removed by Filter: 2"
"Planning time: 105.317 ms"
"Execution time: 17073.396 ms"
私の考えは、インデックスのサイズを部分的に定義して減らすことでした。ほとんどの場合、過去2年間のデータのみが照会されます。これはそれだけで概念実証する必要があり、最終版ではありませんし、それが失敗した原因の
CREATE INDEX idx_detail_table_master_keys
ON detail (master_key)
WHERE master_key in (SELECT master_key FROM master WHERE (extract(year from insert_date) = 2016) or (extract(year from insert_date) = 2015))
:
は、だから私はそのような何かを試してみました。 PGAdminインデックス作成でサブセレクトを使用できないと伝えます。だから私の質問は:それは他のテーブルのデータに基づか、部分インデックスを作成するためにposipleていますか?
私はこのような星座をスピードアップするヒントに感謝します。
よろしく
のコメントを見る[編集]あなたの質問と 'の出力を追加クエリーのために 'explain(analyze、verbose)'を実行します。無関係ですが、 'where'句で古い旧式の暗黙的な結合ではなく、明示的な' JOIN'演算子を実際に使い始めるべきです。 –
@a_horse_with_no_name:EXPLAIN結果に合わせるために、詳細テーブルとクエリをdesimplyfyしました。しかし、その完了;)。 この質問のアイデアは、私の現在のクエリを改善するだけでなく、一般的に同様の構成をスピードアップする方法を学ぶことです。なぜ私はできるだけシンプルにしようとしたのですか? – Mike
@Mike 'CREATE INDEX idx_detail_table_master_insertのように' date(insert_date)のインデックスを作成してみてください。 ONマスターを使用していますbtree(date(insert_date)) ' –