web-dev-qa-db-ja.com

時間ベースのデータを効率的に保存する

レポートソリューションとして、「レポート」と呼ばれる最大5,000万件のレコードを含む大きなテーブルがあります。現在、私はPostgreSQLを パーティションテーブル 機能で毎日使用しています(テーブル名reports_20170101は、2017-01-01のすべてのレコードがそこに保存されることを意味します)。

クエリの例(41秒実行)

SELECT to_char(date_trunc('week', rpt_datetime), 'YYYY-WW') date_week,
SUM(rpt_revenue) revenue FROM reports 
WHERE rpt_datetime < ? 
GROUP BY date_week

EXPLAIN, ANALYZE結果:

https://Gist.github.com/onesvat/be234fbcb6c4d375f9d1dd4151d69391

間隔が小さければ問題ありませんが、間隔を大きくすると遅くなります(20秒以上)。

システムには、128GBのRAM、16スレッド、およびraid0を備えた4つのSSDディスクがあります。

システムが昨日および後方のテーブルを削除または更新することはないため、古いデータを再クエリする必要はありません。これらのタイプのクエリを妥当な時間で処理できるデータベースまたは拡張機能はありますか?

ほとんどの列には、日付などを含むインデックスがあります。実際、次のような追加のインデックスがあります。

btree (date_trunc('week'::text, timezone('Europe/Istanbul'::text, rpt_datetime)))

また、制約:

"reports_20170101_rpt_datetime_check" CHECK (rpt_datetime >= '2017-01-01 00:00:00+00'::timestamp with time zone AND rpt_datetime < '2017-01-02 00:00:00+00'::timestamp with time zone)
4
onesvat

パーティションが日常的に効果的に読み取り専用になる場合は、マテリアライズド・ビューの使用を検討することをお勧めします。マテリアライズドビューの古いデータに対するこれらのクエリの結果を事前に計算できます。

4
David Aldridge