DBAtlas · Database operations atlas

Use a result / query cache

Oracle

-- Result cache at query level:
SELECT /*+ RESULT_CACHE */ city, COUNT(*) FROM customer GROUP BY city;
-- Global mode: ALTER SYSTEM SET result_cache_mode = FORCE;

The Server Result Cache keeps the result in the SGA; it is invalidated automatically when the underlying tables change. RESULT_CACHE_MODE=FORCE applies it to all eligible queries, MANUAL only via the hint. Little benefit on frequently changing tables.

PostgreSQL

-- There is no built-in result cache.
-- Precompute with a materialized view:
CREATE MATERIALIZED VIEW mv_city_summary AS
  SELECT city, COUNT(*) FROM customer GROUP BY city;
REFRESH MATERIALIZED VIEW mv_city_summary;

PostgreSQL does not offer a query result cache; use a materialized view (manual/scheduled REFRESH) or an application-level cache (Redis). Note: the Memoize node provides row-level caching inside a nested loop, not caching of query results.

MySQL

-- Query Cache was REMOVED in MySQL 8.0.
-- Alternative: a materialized summary table or an application cache:
CREATE TABLE city_summary AS SELECT city, COUNT(*) c FROM customer GROUP BY city;

The old query_cache_type was removed entirely in MySQL 8.0 (due to scalability problems). Use the InnoDB buffer pool, summary tables or an external cache (Redis/Memcached) instead.

SQL Server

-- There is no built-in query result cache.
-- Precompute with an indexed (materialized) view:
CREATE VIEW dbo.vw_city_summary WITH SCHEMABINDING AS
  SELECT city, COUNT_BIG(*) c FROM dbo.customer GROUP BY city;
CREATE UNIQUE CLUSTERED INDEX ix ON dbo.vw_city_summary(city);

SQL Server does not keep a result cache (it keeps a plan cache). For repeated aggregations an indexed view is maintained automatically; automatic matching in plans exists only in Enterprise (and Developer) edition, while on Standard the view must be queried with the WITH (NOEXPAND) hint; in addition, the buffer pool keeps frequently read pages in memory.

MongoDB

// There is no built-in query result cache.
// Pre-aggregate and write to a collection ($merge):
db.sale.aggregate([
  { $group: { _id: "$city", t: { $sum: "$amount" } } },
  { $merge: "city_summary" }
])

MongoDB does not offer a result cache; WiredTiger keeps frequently accessed data in memory. For expensive aggregations, use a precomputed summary collection via $merge/$out or an application cache (Redis).

Redis

# Redis is already a cache layer; cache the result manually:
SET query:city_summary "{...}" EX 300
GET query:city_summary
# If already computed, return it with GET; otherwise compute it and write it with SET.

The common cache-aside pattern: if the key exists, return it quickly with GET; otherwise compute from the source and SET it with EX (TTL). Redis usually serves as the result cache for other databases.

Elasticsearch

# Shard request cache (enabled by default for size:0 aggregations):
GET <index>/_search?request_cache=true
{ "size": 0, "aggs": { "city": { "terms": { "field": "city" } } } }
# Setting: PUT <index>/_settings { "index.requests.cache.enable": true }

The shard request cache caches per-shard results of size:0 (aggregation-only) requests; it is invalidated when the index refreshes. Queries with size>0 (returning hits) are not cached by default.

Open in DBAtlas →