สิ่งเหล่านี้เทียบเท่ากันหรือไม่ ถ้าไม่เช่นนั้นทำไม
ดัชนี (user_id1, user_id2) และดัชนี (user_id2, user_id1)
สิ่งเหล่านี้ไม่เทียบเท่าและดัชนีที่พูดโดยทั่วไป (bar, baz) จะไม่มีประสิทธิภาพสำหรับการสืบค้นของแบบฟอร์ม select * from foo where baz=?
เออร์วินได้แสดงให้เห็นว่าดัชนีดังกล่าวสามารถเพิ่มความเร็วในการสืบค้นได้ แต่ผลกระทบนี้มี จำกัด และไม่เป็นแบบเดียวกันกับที่คุณคาดว่าดัชนีจะปรับปรุงการค้นหา - ขึ้นอยู่กับความจริงที่ว่า 'การสแกนแบบเต็ม' ของดัชนีมักจะ เร็วกว่า 'การสแกนเต็มรูปแบบ' ของตารางที่จัดทำดัชนีเนื่องจากคอลัมน์พิเศษในตารางที่ไม่ปรากฏในดัชนี
สรุป: ดัชนีสามารถช่วยให้สืบค้นได้แม้ในคอลัมน์ที่ไม่เป็นผู้นำ แต่เป็นหนึ่งในสองวิธีรองและค่อนข้างน้อยและไม่ได้อยู่ในลักษณะที่น่าทึ่งโดยปกติคุณคาดหวังว่าดัชนีจะช่วยได้เนื่องจากโครงสร้าง btree
วิธีที่ดัชนีสามารถช่วยได้คือหากการสแกนแบบเต็มของดัชนีมีราคาถูกกว่าการสแกนแบบเต็มของตารางอย่างมีนัยสำคัญและ: 1. การค้นหาตารางมีราคาถูก (เพราะมีไม่กี่คนหรือพวกเขาเป็นกลุ่ม) หรือ 2. ดัชนีครอบคลุมดังนั้นจึงไม่มีการค้นหาตารางใด ๆ เลยดูความคิดเห็นของ Erwins ที่นี่
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;
แบบสอบถาม 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