Finding by ID in postgresql very slow on big table
Honestly I have never seen a single value btree lookup take this long.  I don't think your problem is simply in your query.  I think it is elsewhere.

First you say you have a lot of writes.  This probably means you are constantly pushing a lot of stuff out of the buffers and doing a lot of random disk I/O.  I would not be surprised if a lot of the bottleneck is in the general I/O and your lack of RAM.

For 18 million rows, these don't look very large.  They may all fit in memory.

At any rate the first thing to do if had access to the command line on the server would be to take CPU I/O wait vs user vs system time (you may be able to do that elsewhere in your code).  Also run explain with (ANALYSE, BUFFERS, VERBOSE) set so that you can see much more about what is going on.  These should give you an idea if your problem is underwhelming CPU activity, slow RAM, or lots of disk I/O but as it is, there is very little that can be done.

Another thing you can do is this:

VACUUM ANALYSE VERBOSE;


See if that speeds things up.