DBAtlas · 데이터베이스 운영 아틀라스

결과 / 쿼리 캐시 사용

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;

Server Result Cache는 결과를 SGA에 보관하며, 기반 테이블이 변경되면 자동으로 무효화된다. RESULT_CACHE_MODE=FORCE는 적용 가능한 모든 쿼리에, MANUAL은 힌트를 통해서만 적용한다. 자주 변경되는 테이블에서는 효과가 적다.

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은 쿼리 결과 캐시를 제공하지 않는다. materialized view(수동/예약 REFRESH)나 애플리케이션 수준 캐시(Redis)를 사용한다. 참고: Memoize 노드는 nested loop 내부의 행 수준 캐시를 제공하며, 쿼리 결과를 캐시하는 것이 아니다.

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;

기존 query_cache_type은 MySQL 8.0에서 완전히 제거되었다(확장성 문제 때문). 대신 InnoDB buffer pool, 요약 테이블 또는 외부 캐시(Redis/Memcached)를 사용한다.

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는 결과 캐시를 두지 않는다(plan cache는 둔다). 반복되는 집계에는 indexed view가 자동으로 유지된다. 실행 계획에서의 자동 매칭은 Enterprise(및 Developer) 에디션에만 있으며, Standard에서는 WITH (NOEXPAND) 힌트로 뷰를 조회해야 한다. 또한 buffer pool이 자주 읽는 페이지를 메모리에 유지한다.

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는 결과 캐시를 제공하지 않으며, WiredTiger가 자주 접근하는 데이터를 메모리에 유지한다. 비용이 큰 aggregation에는 $merge/$out으로 미리 계산한 요약 컬렉션이나 애플리케이션 캐시(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.

일반적인 cache-aside 패턴: 키가 있으면 GET으로 빠르게 반환하고, 없으면 소스에서 계산해 EX(TTL)와 함께 SET한다. Redis는 보통 다른 데이터베이스의 결과 캐시 역할을 한다.

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 }

shard request cache는 size:0(aggregation 전용) 요청의 샤드별 결과를 캐시하며, 인덱스가 refresh되면 무효화된다. size>0(hit 반환) 쿼리는 기본적으로 캐시되지 않는다.

DBAtlas에서 열기 →