Tôi cảm thấy khó hiểu tại sao có một loạt các đống tải đang diễn ra trong truy vấn này. Theo hiểu biết của tôi, khi không có null (ở hai đầu) trong chỉ mục, việc tìm kiếm ngược lại chỉ mục sẽ nhanh như tìm kiếm trực tiếp và ngược lại.
Tôi nghi ngờ rằng quét tiến / lùi thực sự là một cá trích đỏ, nhưng tôi không thể nhận ra bất kỳ sự khác biệt có ý nghĩa nào khác trong đầu ra giải thích này.
Đây là cách bố trí bảng. Tôi đã ẩn danh hai cột đầu tiên mà tôi tin rằng không liên quan đến vấn đề, nhưng tôi đã giữ chúng và các chỉ mục của chúng để hoàn thiện.
testqueuedb=> \d+ queue
Table "public.queue"
Column | Type | Modifiers | Storage | Stats target | Description
-----------------------+--------------------------+-------------------------------------------------------------+----------+--------------+-------------
foo | character varying(64) | not null | extended | |
bar | numeric(6,0) | not null | main | |
worker | character varying(32) | not null | extended | |
queued | timestamp with time zone | not null default (timeofday())::timestamp without time zone | plain | |
Indexes:
"queue_idx_job" btree (foo, bar, worker)
"queue_idx_worker" btree (worker, queued)
Foreign-key constraints:
"queue_fk_worker" FOREIGN KEY (worker) REFERENCES workers(worker)
Và đây là những giải thích tối thiểu / tối đa khác nhau.
testqueuedb=> explain (analyze, buffers) select min(queued) from queue where worker = 'workername';
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------
Result (cost=0.59..0.60 rows=1 width=0) (actual time=1019.490..1019.490 rows=1 loops=1)
Buffers: shared hit=20194 read=1
InitPlan 1 (returns $0)
-> Limit (cost=0.42..0.59 rows=1 width=8) (actual time=1019.485..1019.486 rows=1 loops=1)
Buffers: shared hit=20194 read=1
-> Index Only Scan using queue_idx_worker on queue (cost=0.42..55480.93 rows=330371 width=8) (actual time=1019.483..1019.483 rows=1 loops=1)
Index Cond: ((worker = 'workername'::text) AND (queued IS NOT NULL))
Heap Fetches: 20224
Buffers: shared hit=20194 read=1
Planning time: 0.197 ms
Execution time: 1019.529 ms
(11 rows)
testqueuedb=> explain (analyze, buffers) select max(queued) from queue where worker = 'workername';
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Result (cost=0.59..0.60 rows=1 width=0) (actual time=0.508..0.509 rows=1 loops=1)
Buffers: shared hit=2 read=3
InitPlan 1 (returns $0)
-> Limit (cost=0.42..0.59 rows=1 width=8) (actual time=0.503..0.503 rows=1 loops=1)
Buffers: shared hit=2 read=3
-> Index Only Scan Backward using queue_idx_worker on queue (cost=0.42..55480.93 rows=330371 width=8) (actual time=0.502..0.502 rows=1 loops=1)
Index Cond: ((worker = 'workername'::text) AND (queued IS NOT NULL))
Heap Fetches: 1
Buffers: shared hit=2 read=3
Planning time: 0.215 ms
Execution time: 0.546 ms
(11 rows)
Tôi thấy các đống tải trong ví dụ đầu tiên này đặc biệt khó hiểu. Có phải tất cả đi xuống để đệm?
Phiên bản Postgres là 9.5.5.
Có khoảng 500.000 hàng cho mỗi công nhân trong bảng và rất ít công nhân riêng biệt - ít hơn mười - khiến tôi nghĩ rằng chỉ số không thực sự được cấu trúc chính xác để bắt đầu, nhưng tôi quan tâm đến sự khác biệt trong các truy vấn này bất kể.
desc
trong truy vấn đó làm cho nó gần như ngay lập tức.
select queued from queue where worker = 'workername' order by queued limit 1;
hiển thị cùng một hành vi / giải thích?