Apakah ini setara? Jika tidak, mengapa?
Indeks (user_id1, user_id2) dan Indeks (user_id2, user_id1)
Ini tidak setara dan secara umum indeks (bar, baz) tidak akan efisien untuk permintaan formulir select * from foo where baz=?
Erwin telah menunjukkan bahwa indeks semacam itu memang dapat mempercepat kueri, tetapi efek ini terbatas dan tidak dengan urutan yang sama seperti yang biasanya Anda harapkan indeks untuk meningkatkan pencarian - itu bergantung pada kenyataan bahwa 'pemindaian penuh' dari indeks sering lebih cepat daripada 'pemindaian penuh' dari tabel yang diindeks karena kolom tambahan dalam tabel yang tidak muncul dalam indeks.
Ringkasan: indeks dapat membantu kueri bahkan pada kolom yang tidak memimpin, tetapi dalam salah satu dari dua cara sekunder dan relatif kecil dan tidak dengan cara dramatis yang biasanya Anda harapkan akan membantu indeks karena struktur btree nya
nb dua cara indeks dapat membantu adalah jika pemindaian penuh indeks secara signifikan lebih murah daripada pemindaian penuh tabel dan baik: 1. pencarian tabel yang murah (karena ada beberapa dari mereka atau mereka mengelompok), atau 2. indeks mencakup sehingga tidak ada pencarian tabel sama sekali oops, lihat komentar Erwins di sini
testbed:
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;
kueri 1 (tanpa indeks, mencapai 74 buffer ):
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
kueri 2 (dengan indeks - pengoptimal mengabaikan indeks - memukul 74 buffer lagi):
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
kueri 2 (dengan indeks - dan kami menipu pengoptimal untuk menggunakannya):
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
Jadi akses melalui indeks dua kali lebih cepat dalam hal ini mengenai 30 buffer - yang dalam hal pengindeksan 'sedikit lebih cepat' !, dan YMMV tergantung pada ukuran relatif tabel dan indeks, bersama dengan jumlah baris yang disaring dan karakteristik clustering dari data dalam tabel
Sebaliknya, pertanyaan pada kolom terkemuka menggunakan struktur btree dari indeks - dalam hal ini mengenai 2 buffer :
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