Ubuntu 12.04でPostgreSQL 9.1を使用しています。
時間範囲内のレコードを選択する必要があります。テーブルにtime_limits
は2つのtimestamp
フィールドと1つのinteger
プロパティがあります。実際のテーブルには、このクエリに関係しない追加の列があります。
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
このテーブルには、およそ2Mのレコードが含まれています。
次のようなクエリには膨大な時間がかかりました。
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
そこで、別のインデックスを追加してみました-PKの逆です:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
パフォーマンスが向上したという印象を受けました。テーブルの中央にあるレコードにアクセスする時間は、より合理的であるようです。40〜90秒の間です。
ただし、時間範囲の中央の値の場合はまだ数十秒です。そして、テーブルの終わりをターゲットにすると(時系列的に)、さらに2倍になります。
私explain analyze
は初めてこのクエリプランを取得しようとしました。
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
-> Bitmap Index Scan on idx_time_limits_phi_start_end (cost=0.00..4714.71 rows=62682 width=0) (actual time=44.437..44.437 rows=0 loops=1)
Index Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
Total runtime: 44.507 ms
検索を最適化するにはどうすればよいですか?あなたはすべての時間が列を一度2つのタイムスタンプスキャン費やされて見ることができますid_phi
に設定されているが0
。そして、タイムスタンプの大きなスキャン(60K行!)がわかりません。彼らは主キーでインデックス付けされていませんidx_inversed
か?
タイムスタンプタイプから別のものに変更する必要がありますか?
GISTおよびGINインデックスについて少し読みました。カスタムタイプの特定の条件でより効率的になる可能性があることを収集します。私のユースケースにとって実行可能なオプションですか?
explain analyze
出力で報告される時間は、クエリがサーバーで必要な時間です。クエリに45秒かかる場合、データベースからクエリを実行するプログラムへのデータの転送に追加時間がかかります。結局62622行であり、各行が大きい(例:長いvarchar
またはtext
列がある)場合、転送時間に影響を与える可能性があります劇的に。
rows=62682 rows
はプランナーの推定値です。クエリは0行を返します。(actual time=44.446..44.446 rows=0 loops=1)