最小/最大クエリができるだけ早く返るように、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時間かかります。
インデックスがあっても、このような大きなテーブルの通常のパフォーマンスですか?このクエリ時間を短縮するにはどうすればよいですか?
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時間近くはかかりません。しかし、explain
とexplain analyze
がなければ、それについて言えることはこれ以上ありません。