Là những tương đương? Nếu không thì tại sao?
Chỉ mục (user_id1, user_id2) và Index (user_id2, user_id1)
Đây không phải là tương đương và chỉ số nói chung (bar, baz) sẽ không hiệu quả cho các truy vấn của biểu mẫu select * from foo where baz=?
Erwin đã chứng minh rằng các chỉ mục như vậy thực sự có thể tăng tốc truy vấn nhưng hiệu ứng này bị hạn chế và không theo thứ tự như bạn thường mong muốn một chỉ mục cải thiện việc tra cứu - nó phụ thuộc vào thực tế là 'quét toàn bộ' chỉ mục nhanh hơn 'quét toàn bộ' bảng được lập chỉ mục do các cột bổ sung trong bảng không xuất hiện trong chỉ mục.
Tóm tắt: các chỉ mục có thể giúp truy vấn ngay cả trên các cột không dẫn đầu, nhưng theo một trong hai cách thứ yếu và tương đối nhỏ và không theo cách kịch tính mà bạn thường mong đợi một chỉ mục sẽ giúp do cấu trúc btree của nó
nb hai cách mà chỉ mục có thể giúp là nếu quét toàn bộ chỉ mục rẻ hơn đáng kể so với quét toàn bộ bảng và: 1. việc tra cứu bảng là rẻ (vì có một vài trong số chúng hoặc chúng được phân cụm), hoặc 2. chỉ số được bao phủ để không có tra cứu bảng nào cả , xin vui lòng xem các bình luận của Erwins tại đây
thử nghiệm:
create table foo(bar integer not null, baz integer not null, qux text not null);
insert into foo(bar, baz, qux)
select random()*100, random()*100, 'some random text '||g from generate_series(1,10000) g;
truy vấn 1 (không có chỉ mục, nhấn 74 bộ đệm ):
explain (buffers, analyze, verbose) select max(qux) from foo where baz=0;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Aggregate (cost=181.41..181.42 rows=1 width=32) (actual time=3.301..3.302 rows=1 loops=1)
Output: max(qux)
Buffers: shared hit=74
-> Seq Scan on stack.foo (cost=0.00..181.30 rows=43 width=32) (actual time=0.043..3.228 rows=52 loops=1)
Output: bar, baz, qux
Filter: (foo.baz = 0)
Buffers: shared hit=74
Total runtime: 3.335 ms
truy vấn 2 (có chỉ mục - trình tối ưu hóa bỏ qua chỉ mục - nhấn lại 74 bộ đệm ):
create index bar_baz on foo(bar, baz);
explain (buffers, analyze, verbose) select max(qux) from foo where baz=0;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Aggregate (cost=199.12..199.13 rows=1 width=32) (actual time=3.277..3.277 rows=1 loops=1)
Output: max(qux)
Buffers: shared hit=74
-> Seq Scan on stack.foo (cost=0.00..199.00 rows=50 width=32) (actual time=0.043..3.210 rows=52 loops=1)
Output: bar, baz, qux
Filter: (foo.baz = 0)
Buffers: shared hit=74
Total runtime: 3.311 ms
truy vấn 2 (có chỉ mục - và chúng tôi lừa trình tối ưu hóa để sử dụng nó):
explain (buffers, analyze, verbose) select max(qux) from foo where bar>-1000 and baz=0;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=115.56..115.57 rows=1 width=32) (actual time=1.495..1.495 rows=1 loops=1)
Output: max(qux)
Buffers: shared hit=36 read=30
-> Bitmap Heap Scan on stack.foo (cost=73.59..115.52 rows=17 width=32) (actual time=1.370..1.428 rows=52 loops=1)
Output: bar, baz, qux
Recheck Cond: ((foo.bar > (-1000)) AND (foo.baz = 0))
Buffers: shared hit=36 read=30
-> Bitmap Index Scan on bar_baz (cost=0.00..73.58 rows=17 width=0) (actual time=1.356..1.356 rows=52 loops=1)
Index Cond: ((foo.bar > (-1000)) AND (foo.baz = 0))
Buffers: shared read=30
Total runtime: 1.535 ms
Vì vậy, truy cập thông qua chỉ mục nhanh gấp đôi trong trường hợp này, đạt 30 bộ đệm - về mặt lập chỉ mục là 'nhanh hơn một chút'!, Và YMMV tùy thuộc vào kích thước tương đối của bảng và chỉ mục, cùng với số lượng hàng được lọc và đặc điểm phân cụm của dữ liệu trong bảng
Ngược lại, các truy vấn trên cột hàng đầu sử dụng cấu trúc btree của chỉ mục - trong trường hợp này nhấn 2 bộ đệm :
explain (buffers, analyze, verbose) select max(qux) from foo where bar=0;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------
Aggregate (cost=75.70..75.71 rows=1 width=32) (actual time=0.172..0.173 rows=1 loops=1)
Output: max(qux)
Buffers: shared hit=38
-> Bitmap Heap Scan on stack.foo (cost=4.64..75.57 rows=50 width=32) (actual time=0.036..0.097 rows=59 loops=1)
Output: bar, baz, qux
Recheck Cond: (foo.bar = 0)
Buffers: shared hit=38
-> Bitmap Index Scan on bar_baz (cost=0.00..4.63 rows=50 width=0) (actual time=0.024..0.024 rows=59 loops=1)
Index Cond: (foo.bar = 0)
Buffers: shared hit=2
Total runtime: 0.209 ms