Low cache hit ratio (buffer/cache hit)
The cache hit ratio is low; data is constantly read from disk (or from the source). Determine whether the problem is in the DB buffer/shared cache or in the Redis/application cache, then measure and fix it.
Which cache has a low hit ratio?
Measure the hit ratio and isolate the problem: is the database buffer/shared cache low (high physical reads), or is the Redis/application cache seeing many misses and evictions?
SELECT ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct
FROM v$sysstat pr, v$sysstat dbg, v$sysstat cg
WHERE pr.name='physical reads' AND dbg.name='db block gets' AND cg.name='consistent gets';- DB buffer/shared cache hit ratio is low
- Many misses / evictions in the Redis/application cache
Why is it reading from disk: size or scan pattern?
There are two typical causes of a low buffer hit ratio: the frequently accessed data (working set) does not fit in memory (cache too small), or large full table scans pollute the cache with single-use blocks and push useful pages out.
SELECT component, current_size/1024/1024 AS mb FROM v$sga_dynamic_components WHERE component LIKE '%buffer cache%';
SELECT sql_id, disk_reads, executions FROM v$sql ORDER BY disk_reads DESC FETCH FIRST 10 ROWS ONLY;- Working set does not fit in RAM (cache too small)
- Full table scans pollute the cache
Why the Redis misses: maxmemory eviction or TTL/key management?
If the Redis hit ratio is low, either memory has hit maxmemory and keys are being evicted, or TTL management/the caching pattern for the keys is weak (cold keys, low reuse).
INFO memory
# used_memory, maxmemory, maxmemory_policy, evicted_keys
CONFIG GET maxmemory-policy
INFO keyspace
# Key count and expires (keys with TTL) ratio per db- maxmemory full, high eviction
- Weak TTL/key pattern (low reuse)
Root cause: the cache is too small for the working set
The frequently accessed data is larger than the allocated buffer/cache, so it is constantly evicted and re-read from disk. Hit ratio is low, physical reads are high.
Root cause: the scan pattern pollutes the cache
Large full table scans fill the cache with blocks that are used once and discarded, pushing hot pages out; this lowers the hit ratio.
Root cause: Redis maxmemory eviction
Redis memory has hit the maxmemory limit; old keys are evicted to make room for new ones (evicted_keys keeps rising). This loses entries that are still needed and lowers the hit ratio.
Root cause: weak TTL / caching pattern
Either keys get no TTL at all, so memory fills with cold data, or the caching pattern has low reuse, so most requests end up as misses.