이것들은 동등합니까? 그렇지 않다면 왜?
인덱스 (user_id1, user_id2) 및 인덱스 (user_id2, user_id1)
이것들은 동일하지 않으며 일반적으로 말해서 색인 (bar, baz)은 형식의 쿼리에 효율적이지 않습니다. select * from foo where baz=?
Erwin 은 그러한 인덱스가 실제로 쿼리 속도를 높일 수 있음 을 보여 주 었지만,이 효과는 제한적이며 일반적으로 인덱스가 조회를 개선 할 것으로 예상하는 순서와 같지 않습니다. 인덱스의 '전체 스캔'이 종종 있다는 사실에 의존합니다 인덱스에 나타나지 않는 테이블의 추가 열로 인해 인덱스 된 테이블의 '전체 스캔'보다 빠릅니다.
요약 : 인덱스는 선행이 아닌 열의 쿼리에도 도움이 될 수 있지만 두 가지 보조적이며 비교적 사소한 방법 중 하나를 사용하지만 일반적으로 인덱스가 btree 구조로 인해 도움이 될 것으로 예상되는 방식은 아닙니다.
1. 테이블 조회가 (거기에 그들 중 몇 가지하거나 클러스터 때문에) 저렴 : 전체 인덱스 스캔은 테이블과 하나의 전체 검사보다 훨씬 저렴 경우 인덱스가 도울 수있는 두 가지 방법 NB 있습니다 또는 2. 인덱스입니다 커버 그래서 전혀 테이블 조회가 없습니다 죄송합니다, Erwins 코멘트보기 여기가
테스트 베드 :
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;
쿼리 1 (인덱스 없음, 74 버퍼 치기 ) :
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
쿼리 2 (인덱스-옵티마이 저는 인덱스를 무시하고 74 버퍼를 다시 칩니다 ) :
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
쿼리 2 (인덱스 사용-최적화 프로그램을 사용하여 트릭 사용) :
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
따라서이 경우 인덱스를 통한 액세스는 30 개의 버퍼에 도달 합니다 (인덱싱 측면에서 '약간 빠름') .YMMV는 테이블 및 인덱스의 상대적 크기와 필터링 된 행 수 및 클러스터링 특성에 따라 다릅니다. 테이블의 데이터
대조적으로 선행 열의 쿼리는 인덱스의 btree 구조를 사용합니다.이 경우에는 2 개의 버퍼가 발생합니다 .
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