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 はクエリ結果キャッシュを提供しない。マテリアライズドビュー(手動/スケジュールの REFRESH)またはアプリケーションレベルのキャッシュ(Redis)を使用する。注: Memoize ノードはネステッドループ内の行レベルのキャッシュを提供するもので、クエリ結果のキャッシュではない。

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 バッファプール、サマリーテーブル、または外部キャッシュ(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 は結果キャッシュを保持しない(プランキャッシュは保持する)。繰り返される集計にはインデックス付きビューが自動的に維持される。実行計画での自動マッチングは Enterprise(および Developer)エディションのみで、Standard では WITH (NOEXPAND) ヒントでビューをクエリする必要がある。加えて、バッファプールは頻繁に読まれるページをメモリに保持する。

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 は頻繁にアクセスされるデータをメモリに保持する。高コストな集計には、$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 }

シャードリクエストキャッシュは size:0(集計のみ)のリクエストのシャードごとの結果をキャッシュする。インデックスがリフレッシュされると無効化される。size>0(ヒットを返す)のクエリはデフォルトではキャッシュされない。

DBAtlas で開く →