0

このスキーマにほぼ従うテーブルがあります。

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

これをより効率的に行い、<= 結合を削除する方法についてのアイデアはありますか? これにより、ネストされたループが発生し、オーバーヘッドが大きくなりすぎます。

4

1 に答える 1

0

Citus では、ロールアップ テーブルを使用して、リアルタイム データに対するクエリの中間結果を作成しています。日ごと (またはおそらく時間単位) の集計を計算し、後でこれらの中間値を使用して月の集計を計算できます。

このソリューションでは、結合を使用する必要がなくなるわけではありませんが、計算コストは​​大幅に削減されます。

ロールアップ テーブルの使用方法については、ドキュメントを参照してください。Citus を使用してテーブルを配布していない場合でも、ここにある情報を参考にしてください。

于 2019-06-13T11:20:15.583 に答える