テーブルからすべてまたはほとんどの行を取得する場合、このタイプのクエリの最速の方法は、通常、最初に集計/明確化することです。 後で参加します :
SELECT *
FROM products p
JOIN (
SELECT DISTINCT ON (product_id) *
FROM meta
ORDER BY product_id, id DESC
) m ON m.product_id = p.id;
meta
の行数が増える products
の行ごと 、パフォーマンスへの影響が大きくなります。
もちろん、ORDER BY
を追加することをお勧めします サブクエリの句はwhichを定義します サブクエリの各セットから選択する行。 @Craigと@Clodoaldoはすでにそれについてあなたに話しました。 meta
を返します id
が最も高い行 。
SQLフィドル。
DISTINCT ON
の詳細 :
- 各GROUPBYグループの最初の行を選択しますか?
パフォーマンスを最適化する
それでも、これが常に最速のソリューションであるとは限りません。データ分散に応じて、他のさまざまなクエリスタイルがあります。別の結合を含むこの単純なケースの場合、これは大きなテーブルを使用したテストでかなり高速に実行されました。
SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM (
SELECT product_id, max(id) AS meta_id
FROM meta
GROUP BY 1
) sub
JOIN meta m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;
わかりにくいid
を使用しない場合 列名として、名前の衝突に遭遇することはなく、単にSELECT p.*, m.*
と書くことができます。 。 (私は決して id
を使用する 列名として。)
パフォーマンスが最も重要な要件である場合は、より多くのオプションを検討してください。
MATERIALIZED VIEW
meta
から事前に集計されたデータを使用 、データが(大幅に)変更されない場合。- ルーズインデックススキャンをエミュレートする再帰CTE 大きいの場合
meta
多くのテーブル 商品ごとの行数(比較的少数の個別のproduct_id
)。
これは、テーブル全体でDISTINCTクエリにインデックスを使用することを私が知っている唯一の方法です。