2017-10-24 15 views
0

私は「イベントソーシング」スタイルで組織されたテラバイトのデータを持っています。あるキーに対するすべての更新は、レベルと呼ばれる更新の「時間」とともに格納されます。内部クエリは、特定の時刻またはその前のすべてのキーの最新の値を検索します。次に、外部クエリによって特定のキーが選択されます。グループ内の最新のキーを繰り返し照会する方法は?

私はこのクエリーを特定の時間(多くの場合過去)に100回実行しますが、多くのキーで実行します。 外部クエリのみを繰り返し実行するように内部クエリをキャッシュする方法はありますか?または、このクエリを書くためのよりよい方法がありますか?

LVL KEY VALUE 
1  a 10 
1  b 11 
1  c 12 
1  d 13 
2  a 20 
2  b 21 
3  c 32 
4  b 41 

および表:いくつかの可能な解決策が

create table storage (
    lvl integer, 
    key text, 
    value text, 
    primary key (key, lvl) 
) ; 
+0

「私はどちらかこれらのキャッシュされた値を格納するための補助テーブルを使用して解答し、ユーザー定義関数を書き込むそのテーブルから選択するか、値をゆっくりと道を選択して、テーブルに挿入するつもりだったが、私はドン実現UDFの構文を十分に理解しています。とにかくそれは私が試みるものです。私は、高価なサブクエリを実行することを避ける 'ON CONFLICT'のようなものでこれを行うための文書化された方法はないと思います。 – sudo

+0

テーブルの例には 'time'カラムはありません。 BTW: 'time'は予約語(データ型)です。 – wildplasser

+0

"時間"を削除するために私の例を修正します。実際のクエリは、人々を混乱させる用語を使用します。 – projectshave

答えて

0

をされています

--Using CTE to create a temporary table max_storage 
WITH max_storage AS (
    select max(time), key from storage as s1 
       where s1.time <= 4 GROUP BY key 
) 
SELECT s.value FROM storage s JOIN max_storage m ON (s.time = m.time AND s.key = m.key); 

--Simpler solution using DISTINCT ON but not using "cache" as you asked 
SELECT DISTINCT ON (key) value FROM storage AS s1 WHERE s1.time <= 4 ORDER BY key, time DESC; 

時間とキー列がインデックス化されている。ここ

select value from storage 
where lvl = (select max(lvl) from storage as s1 
       where s1.key = storage.key and s1.lvl <= 4) 
and key = 'd'; 

は、テーブルですか?そうでない場合は、そうすることをお勧めします。また あなたのオブジェクトの予約語を使用しないでください。

CTEhereと約DISTINCT ONhereについての詳細情報

+0

'max_storage'を時間値でパラメータ化できますか?私はそれをハードコーディングすることはできません、時間は永遠に続きます。 – projectshave

関連する問題