Hallo!
Um meine Test-Tabelle und den Index zu erstellen (ich hab postgres 9.6.1 auf Win10, alles auf default):
CREATE TABLE meineTabelle (spalte1 bigint, spalte1_Index bigint, spalte2 text);
INSERT INTO meineTabelle SELECT i,i, md5(random()::text) FROM generate_series(1, 1000000) AS i;
create index meinindex on meinetabelle (Spalte1_Index);
Dieses select verwendet nur Daten, die im Index vorkommen (Spalte spalte1_index):
select spalte1_index from meinetabelle where spalte1_index > 990 ;
Trotzdem entscheidet sich postgres für Sec Scan. Warum?:
postgres=# explain analyse verbose select spalte1_index from meinetabelle where spalte1_index > 990 ;
QUERY PLAN
------------------------------------------------------------------------------------------------------------
Seq Scan on public.meinetabelle (cost=0.00..22810.00 rows=999039 width=8) (actual time=0.156..1050.511 rows=999010 loops=1)
Output: spalte1_index
Filter: (meinetabelle.spalte1_index > 990)
Rows Removed by Filter: 990
Planning time: 0.191 ms
Execution time: 1938.472 ms
Die Kosten für einen Index Only Scan sind: cost=0.42…25636.28 ( erzwungen durch: set enable_seqscan=off; )
Erst wenn die Zeilenanzahl vom Result Set sehr klein wird, schwenkt postgres auf Index Only Scan um (where-Klausel verändert):
postgres=# explain analyse verbose select spalte1_index from meinetabelle where spalte1_index > 993930 ;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Index Only Scan using meinindex on public.meinetabelle (cost=0.42..160.59 rows=5495 width=8) (actual time=0.357..6.138 rows=6070 loops=1)
Output: spalte1_index
Index Cond: (meinetabelle.spalte1_index > 993930)
Heap Fetches: 0
Planning time: 0.206 ms
Execution time: 11.718 ms
Danke