列を持つPostgreSQLテーブルPrices
があります。
price
(10進数)product_id
(整数)もあります created_at
およびupdated_at
列。
価格は定期的に更新され、古い価格はテーブルに保持しています。特定の製品について、表の最後の価格は現在の価格です。
特定の製品の最終価格を取得する最も効率的な方法は何ですか。
product_id
と最後のレコードのクエリactive
(ブール)を追加して最新の価格をマークし、複合インデックス(product_id
およびactive
)ソリューションに関係なく、product_idのインデックスが必要になります。
Updated_at列にインデックスがあり、必要なのは、指定した「特定の製品」をフェッチすることだけである場合は、次のようにします。
select *
from Prices
where product_id = ?
order by updated_at desc
limit 1
しかし、希望する結果が得られなかった場合、または多くの製品の現在の価格を取得する必要がある場合は、アクティブな列を追加し、新しい列以外のすべての価格でNに設定するオプションを試してみます。価格の更新後、a_horse_with_no_nameで提案されているように、アクティブな部分インデックスを作成します。以前の価格行をアクティブにしないように更新するという複雑なレイヤーを追加するので、必要な場合にのみそこに行きます。
データベースの残りの部分の知識がなければ、製品の価格のフェッチを高速化するために少しの非標準形式を用意することができます(各アイテムに1つの価格があると仮定します)。
price
テーブルにlast_price
of type product
という名前の新しい列を作成し、price
テーブルにトリガーAFTER INSERT ON EACH ROW
を作成するだけです。新しい価格が作成されるたびに、関連製品が最新の価格で更新されます。この方法では、製品をフェッチするたびに、その最終価格もフェッチします。
バージョン9.3以降、PostgreSQLはマテリアライズドビューをサポートしています。これは、データを非正規化し、書き込み用の通常の形式と読み取り用の非正規化ビューを維持するための良い方法です。ビューの更新は、PostgresのLISTEN/NOTIFYメカニズムによってトリガーできます。