Postgres Query not using Index but faster with Index
It seems that PostgreSQL is overestimating the cost of an index scan, which leads it to prefer a hash join over a nested loop join.
There are two parameters that tell PostgreSQL about the hardware and influence its estimate of the cost of an index scan:

random_page_cost: the greater that is compared to seq_page_cost, the more expensive PostgreSQL will estimate an index scan's random I/O compared to sequential I/O. So you can lower that parameter to encourage index scans.

effective_cache_size: this tells the optimizer how much memory is available for caching data. If the value is high, it will assume that indexes are cached and price index scans lower.


Perhaps adjusting these parameters will change PostgreSQL's mind here, although the cost estimates are suspiciously far apart.