Tôi sử dụng PostgreSQL 9.1 trên Ubuntu 12.04.
Tôi cần chọn các bản ghi trong một khoảng thời gian: bảng của tôi time_limits
có hai timestamp
trường và một thuộc integer
tính. Có các cột bổ sung trong bảng thực tế của tôi không liên quan đến truy vấn này.
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
Bảng này chứa khoảng 2 triệu bản ghi.
Các câu hỏi như sau mất rất nhiều thời gian:
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';
Vì vậy, tôi đã thử thêm một chỉ mục khác - nghịch đảo của PK:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
Tôi có ấn tượng rằng hiệu suất được cải thiện: Thời gian truy cập các bản ghi ở giữa bảng có vẻ hợp lý hơn: ở đâu đó trong khoảng từ 40 đến 90 giây.
Nhưng vẫn còn vài chục giây cho các giá trị ở giữa phạm vi thời gian. Và hai lần nữa khi nhắm mục tiêu cuối bảng (nói theo trình tự thời gian).
Tôi đã thử explain analyze
lần đầu tiên để có được kế hoạch truy vấn này:
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
Tôi có thể làm gì để tối ưu hóa tìm kiếm? Bạn có thể thấy tất cả thời gian được dành để quét hai cột dấu thời gian một lần id_phi
được đặt thành 0
. Và tôi không hiểu bản quét lớn (60K hàng!) Trên dấu thời gian. Họ không được lập chỉ mục bởi khóa chính và idx_inversed
tôi đã thêm?
Tôi có nên thay đổi từ loại dấu thời gian sang thứ khác không?
Tôi đã đọc một chút về các chỉ số GIST và GIN. Tôi tập hợp họ có thể hiệu quả hơn trong các điều kiện nhất định cho các loại tùy chỉnh. Nó có phải là một lựa chọn khả thi cho trường hợp sử dụng của tôi không?
explain analyze
đầu ra là thời gian truy vấn cần thiết trên máy chủ . Nếu truy vấn của bạn mất 45 giây, thì thời gian bổ sung được dành để chuyển dữ liệu từ cơ sở dữ liệu sang chương trình chạy truy vấn Sau tất cả các hàng là 62682 và nếu mỗi hàng lớn (ví dụ: có hàng dài varchar
hoặc text
cột), điều này có thể ảnh hưởng đến thời gian chuyển quyết liệt
rows=62682 rows
là ước tính của người lập kế hoạch . Truy vấn trả về 0 hàng. (actual time=44.446..44.446 rows=0 loops=1)