このスキーマにほぼ従うテーブルがあります。
Table Name: history
╔════╤══════╤══════════╤═════╤═════════════════════╗
║ id │ stat │ stat_two │ ... │ updated_at ║
╠════╪══════╪══════════╪═════╪═════════════════════╣
║ 1 │ 100 │ 5 │ ... │ 2019-01-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 105 │ 7 │ ... │ 2019-01-02 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 300 │ 10 │ ... │ 2019-02-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 1 │ 700 │ 20 │ ... │ 2019-05-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 50 │ 0 │ ... │ 2019-01-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 55 │ 0 │ ... │ 2019-01-02 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 75 │ 3 │ ... │ 2019-02-01 12:30 PM ║
╟────┼──────┼──────────┼─────┼─────────────────────╢
║ 2 │ 90 │ 7 │ ... │ 2019-05-01 12:30 PM ║
╚════╧══════╧══════════╧═════╧═════════════════════╝
テーブルはとても大きいです。
次の結果を生成しようとしていますが、フィルタリングにはいくつかの IDS (1 と 2 のみなど) のみが含まれます。
╔═════════╤═══════════════════╤═══════════════════════════════════════════════╤═══════════════════════════════════════════════════╗
║ month │ count_of_ids_seen │ sum_of_(last_seen_stat_for_that_month per ID) │ sum_of_(last_seen_stat_two_for_that_month per ID) ║
╠═════════╪═══════════════════╪═══════════════════════════════════════════════╪═══════════════════════════════════════════════════╣
║ 2019-01 │ 2 │ 160 │ 7 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-02 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-03 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-04 │ 2 │ 375 │ 13 ║
╟─────────┼───────────────────┼───────────────────────────────────────────────┼───────────────────────────────────────────────────╢
║ 2019-05 │ 2 │ 790 │ 27 ║
╚═════════╧═══════════════════╧═══════════════════════════════════════════════╧═══════════════════════════════════════════════════╝
last_value ウィンドウ関数を試してみましたが、表示されるレコードを取得できますが、レコードがテーブルに表示されない場合、データが遅れる必要があるという問題があります。たとえば、月 3 の場合、レコードがないため、これより前の日付の最後に確認されたレコードを取得する必要があると想定されます。
私の現在のソリューションは <= 結合を使用していましたが、これがボトルネックであり、何百万もの ID を試行すると、遅すぎて、必要な速度で実行されません。
私は次のように generate_series に対して参加していました:
FROM
(SELECT month::date FROM generate_series('2018-03-01'::date, '2019-06-01'::date, '1 month') month) d
LEFT JOIN
history h
ON date_trunc('month', h.updated_at) <= d.month
これをより効率的に行い、<= 結合を削除する方法についてのアイデアはありますか? これにより、ネストされたループが発生し、オーバーヘッドが大きくなりすぎます。