Saya menggunakan PostgreSQL 9.1 di Ubuntu 12.04.
Saya perlu memilih catatan dalam rentang waktu: meja saya time_limits
memiliki dua timestamp
bidang dan satu integer
properti. Ada kolom tambahan di tabel aktual saya yang tidak terlibat dengan kueri ini.
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Tabel ini berisi sekitar 2 juta catatan.
Pertanyaan seperti berikut ini membutuhkan banyak waktu:
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';
Jadi saya mencoba menambahkan indeks lain - kebalikan dari PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Saya mendapat kesan bahwa kinerja meningkat: Waktu untuk mengakses catatan di tengah meja tampaknya lebih masuk akal: di suatu tempat antara 40 dan 90 detik.
Tetapi masih beberapa puluh detik untuk nilai di tengah rentang waktu. Dan dua kali lagi ketika menargetkan ujung meja (berbicara secara kronologis).
Saya mencoba explain analyze
untuk pertama kalinya untuk mendapatkan paket permintaan ini:
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
Apa yang bisa saya lakukan untuk mengoptimalkan pencarian? Anda dapat melihat semua waktu yang dihabiskan memindai dua kolom cap waktu setelah id_phi
diatur ke 0
. Dan saya tidak mengerti pemindaian besar (baris 60K!) Pada cap waktu. Bukankah mereka diindeks oleh kunci primer dan idx_inversed
saya menambahkan?
Haruskah saya mengubah dari jenis stempel waktu ke yang lain?
Saya telah membaca sedikit tentang indeks GIST dan GIN. Saya rasa mereka bisa lebih efisien pada kondisi tertentu untuk jenis kustom. Apakah ini opsi yang layak untuk kasus penggunaan saya?
explain analyze
output adalah waktu permintaan yang diperlukan di server . Jika kueri Anda membutuhkan waktu 45 detik, maka waktu tambahan dihabiskan untuk mentransfer data dari database ke program yang menjalankan kueri. Lagipula 62682 baris dan jika setiap baris besar (misalnya panjang varchar
atau text
kolom), ini dapat memengaruhi waktu transfer secara drastis.
rows=62682 rows
adalah perkiraan perencana . Kueri mengembalikan 0 baris. (actual time=44.446..44.446 rows=0 loops=1)