boltPlan cache
Running a SPARQL query costs two things: translating the SPARQL into SQL, and running that SQL. Each connection caches its translations, so a repeated query pays only for running it. There is nothing to configure.
What counts as the same query
The cache is keyed on the shape of the query, not its exact text:
- Whitespace and layout don't matter.
- Queries that differ only in constants (IRIs, literals, numbers) share one entry. Each run still uses its own values.
- A different shape (another triple pattern, a
FILTER, an aggregate) gets its own entry.
In a new connection, over the graph from Composing with SQL:
SELECT pgrdf.stats() -> 'plan_cache_local_size'; -- 0
SELECT sparql->>'o' AS o FROM pgrdf.sparql('PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?o WHERE { <http://example.com/alice> foaf:knows ?o }'); -- bob, carol
SELECT sparql->>'o' AS o FROM pgrdf.sparql('PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?o WHERE { <http://example.com/bob> foaf:knows ?o }'); -- carol
SELECT pgrdf.stats() -> 'plan_cache_local_size'; -- 1: same shape, one entry
SELECT sparql FROM pgrdf.sparql('PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?p (COUNT(?o) AS ?c) WHERE { ?p foaf:knows ?o } GROUP BY ?p ORDER BY ?p');
SELECT pgrdf.stats() -> 'plan_cache_local_size'; -- 2: a new shapeYour application can build queries with different constants freely, without flooding the cache.
Cached queries see current data
A cached translation runs against the data as it is now. Graphs added, loaded or cleared after a query was cached show up in its next run. You don't need to invalidate anything after changing data.
One cache per connection
Each connection's cache starts empty when the connection opens and disappears when it closes. A connection pool keeps connections, and their caches, alive between requests. Opening a new connection for every query makes every query pay for translation.
Watching it
SELECT s->'plan_cache_local_size' AS this_connection,
s->'plan_cache_hits' AS hits_all_connections,
s->'plan_cache_misses' AS misses_all_connections
FROM pgrdf.stats() AS s;plan_cache_local_size counts this connection's entries. The hit and miss counters are cumulative across all connections on the server; see Counters and health.
plan_cache_clear() exists as an internal diagnostic; see Cache control. Closing the connection has the same effect.