Creating a differently-ordered index on `triples`
See Generic Query Plans in PSQL 9.1. In that page we describe how PostgreSQL 9.1 wanted to use generic query plans for prepared statements, and how these plans were slower that what would be planned and executed for a regular query.
In addition, after upgrading to PostgreSQL 9.4, we've found that adding a compound index on the `triples' columns `subject`, `predicate`, `object`, and `context`, but in a different order than they were specified in an existing index, sped up some remaining slow queries.
See The Gist. (That Gist was also created to confirm a report that repeat `execute` statements do not use the same query plan, after the fifth execution.)
The upshot is that the order of columns in a compound index appears to matter, even if all columns in the compound index are specified in the WHERE condition of the query. We already had the following index on `triples`:
"idx_triples_cspo" btree (context, subject, predicate, object) WHERE deleted = false
When we did an `EXPLAIN` on a query with a `WHERE` clause on those four columns, the plan came back with a "Filter" condition on its "Index Scan" node. The index scan was on a 3-column index that did not include the `context` column. (Not the existing four-column index that did.)
We then added an index with a different ordering, like so:
create index idx_triples_spoc on triples (subject, predicate, object, context) where deleted = false; analyze triples;
Running `EXPLAIN` again revealed an "Index Scan" on the four-column index without the "Filter" condition.
As the Gist notes, the `subject` column is the highest-cardinality column out of the four in question. It appears that putting it first makes a difference.
It's true that the estimated total cost is the same between queries, but we have not been getting slow queries logged anymore after making this change.