Did you try using prepared statement so the compilation is done once and compiled results are reused each time that query is run?
- parameters are opaque to planner, so it prefers (or is even forced to?) to choose generic vs specific plans
- it doesn't play nice with pg_bouncer in transaction mode
Oracle has an option to detect literals (CURSOR_SHARING) and essentially replace them with binds internally, in order to increase performance and stop the query pool getting filled up with the same statement(s).