Reputation: 963
I think both cases only need to scan the indexes, but this is not the case. Only BTree index is used.
The following is an example
drop table if exists test;
create table test
(
id serial4 primary key,
name varchar(255) not null,
score int not null
);
I inserted 1,000,000 rows. 9867 rows score is 0.
Explain With Hash Indexes
drop index if exists test_score_zero;
create index test_score_zero on test using hash (id) where score = 0;
explain select id from test where score = 0;
Explain With BTree Indexes
drop index if exists test_score_zero;
create index test_score_zero on test using btree (id) where score = 0;
explain select id from test where score = 0;
The Hash Indexes result is
Gather (cost=1000.00..13578.03 rows=9867 width=4)
Workers Planned: 2
-> Parallel Seq Scan on test (cost=0.00..11591.33 rows=4111 width=4)
Filter: (score = 0)
The BTree Indexes result is
Index Only Scan using test_score_zero on test (cost=0.29..262.58 rows=9867 width=4)
PostgreSQL Version:
psql (PostgreSQL) 12.5 (Ubuntu 12.5-1.pgdg18.04+1)
Upvotes: 0
Views: 597
Reputation:
As documented in the manual hash indexes simply do not support "Index Only Scan"
To solve this performance problem, PostgreSQL supports index-only scans [...]
The index type must support index-only scans. B-tree indexes always do. GiST and SP-GiST indexes support index-only scans for some operator classes but not others. Other index types have no support.
(emphasis mine)
There are only very few reasons to use a hash index instead of a B-Tree index and if you expect that Index Only Scan will help performance for your queries substantially, just stick with a B-Tree index.
Upvotes: 1