web-dev-qa-db-ja.com

PostgreSQLの大きなテーブルの最小/最大クエリを最適化する方法

最小/最大クエリができるだけ早く返るように、PostgreSQLのテーブルにどのようにインデックスを付けますか?

数億行の大きなテーブルがあります。 source_idおよびレコードが最後に更新された日付としての各行。各source_idの統計情報、具体的には各source_idの最小および最大の日付範囲を収集したいと思います。

だから私は自分のテーブルにこのインデックスを作成しました:

 CREATE INDEX CONCURRENTLY mydata_source_last_updated_date ON mydata (source_id, last_updated_date ASC);

しかし、ソースごとの最小日付をクエリしようとすると:

SELECT source_id, MIN(last_updated_date) FROM mydata GROUP BY source_id;

クエリの完了には約1時間かかります。

インデックスがあっても、このような大きなテーブルの通常のパフォーマンスですか?このクエリ時間を短縮するにはどうすればよいですか?

2
Cerin

Source_idの数十の異なる値のみを使用すると、作成したインデックスで ルーズインデックススキャン、別名「スキップスキャン」 を使用して高速に実行できます。残念ながらPostgreSQLはそれらを自動的に計画しないので、再帰クエリを使用して強制的に1つにする必要があります。

with recursive t as ( 
   select min(source_id) as col from mydata 
   union all 
   select (select min(source_id) from mydata where source_id>t.col)
      from t where t.col is not null) 
select 
  col, 
  (select min(last_updated_date) from mydata where source_id=col),
  (select max(last_updated_date) from mydata where source_id=col)
  from t;

これに頼らなくても、最初に書いたとおりにクエリを実行するだけで1時間近くはかかりません。しかし、explainexplain analyzeがなければ、それについて言えることはこれ以上ありません。

3
jjanes