MySQL Query Cache (Deprecated)
debt(d7/e7/b5/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints note a code_pattern (query_cache_size or SELECT SQL_CACHE in MySQL 8+), but the real danger is on write-heavy workloads where the global mutex silently degrades performance without throwing errors. In MySQL 8 the setting is simply ignored or absent, and SELECT SQL_CACHE is silently a no-op — neither the app nor a standard linter flags the problem. Only careful code review, MySQL configuration audits, or runtime performance profiling reveals the issue.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix says to implement application-level caching with Redis or Memcached instead. This is not a one-line swap — it requires identifying all code paths that implicitly relied on the query cache, adding a caching layer (Redis/Memcached), designing cache keys and TTL strategies, and potentially touching many queries and service components across the codebase. This spans multiple files and represents a significant architectural shift in caching strategy.
Closest to 'persistent productivity tax' (b5). The applies_to covers both web and cli contexts, meaning any MySQL-backed project can be affected. Developers who learned pre-MySQL 8 carry a mental model of free implicit caching that no longer exists; every performance investigation and new feature must account for the absence of query cache and the need for explicit application-level caching. This is a persistent tax on multiple work streams but doesn't fully define the system's shape.
Closest to 'serious trap' (t7). The misconception field states directly: 'Enabling MySQL query cache improves performance' — but on write-heavy workloads it actually degrades performance via the global mutex. Additionally, in MySQL 8 the feature is completely removed and SELECT SQL_CACHE is silently ignored, contradicting the expectation of pre-8 developers who assume it still works. This contradicts behavior from a previous version of the same tool and from how similar caching concepts behave elsewhere, making it a serious trap.
Also Known As
TL;DR
Explanation
MySQL's built-in query cache stored SELECT results and invalidated the entire table's cached results on any write. Under write-heavy workloads it became a contention point — every INSERT/UPDATE/DELETE invalidated potentially thousands of cached queries. It was deprecated in MySQL 5.7.20 and removed in 8.0. Modern alternatives are application-level caches (Redis, Memcached) which give control over cache keys, TTLs, and invalidation logic.
Common Misconception
Why It Matters
Common Mistakes
- Expecting query_cache_size to exist in MySQL 8 — it was fully removed.
- Relying on implicit database-level caching instead of explicit application caching.
- Using SELECT SQL_CACHE in queries targeting MySQL 8 — silently ignored.
Avoid When
- Do not set query_cache_size in MySQL 8 config — it causes startup errors as the option was fully removed.
- Do not rely on database-level caching — application-level caching is more predictable and scalable.
When To Use
- Implement application-level caching with Redis or Memcached — gives full control over cache keys and TTLs.
Code Examples
-- MySQL 8: query_cache_size no longer exists
-- query_cache_size = 64M -- This config option causes startup error in MySQL 8
// Application-level caching with Redis (preferred)
$cacheKey = 'user:' . $userId;
$user = $redis->get($cacheKey);
if ($user === null) {
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$userId]);
$user = $stmt->fetch();
$redis->setex($cacheKey, 300, json_encode($user)); // 5 min TTL
}
return json_decode($user, true);