Databases Reference
In-Depth Information
is frequently true). You can keep large results from being cached by lowering the value
of the query_cache_limit variable, which can sometimes help achieve a better balance
between fragmentation and the overhead of storing results in the cache.
You can detect query cache fragmentation by examining the Qcache_free_blocks status
variable, which shows you how many blocks in the query cache are of type FREE . In the
final configuration shown in Figure 7-4 , there are two free blocks. The worst possible
fragmentation is when there's a slightly-too-small free block between every pair of
blocks used to store data, so every other block is a free block. Thus, if Qcache
_free_blocks approaches Qcache_total_blocks / 2 , your query cache is severely frag-
mented. If the Qcache_lowmem_prunes status variable is increasing and you have a lot of
free blocks, fragmentation is causing queries to be deleted from the cache
prematurely.
You can defragment the query cache with FLUSH QUERY CACHE . This command compacts
the query cache by moving all blocks “upward” and removing the free space between
them, leaving a single free block at the bottom. Contrary to its name, it does not remove
queries from the cache; that's what RESET QUERY CACHE does. FLUSH QUERY CACHE blocks
access to the query cache while it runs, which effectively locks the whole server, so be
very careful with it. One rule of thumb for query cache sizing is to keep it small enough
that the stalls caused by FLUSH QUERY CACHE are acceptably short.
Improving query cache usage
If your query cache isn't fragmented but you're still not getting a good hit rate, you
might have given it too little memory. If the server can't find any free blocks that are
large enough to use for a new block, it must “prune” some queries from the cache.
When the server prunes cache entries, it increments the Qcache_lowmem_prunes status
variable. If this value increases rapidly, there are two possible causes:
• If there are many free blocks, fragmentation is the likely culprit (see the previous
section).
• If there are few free blocks, it might mean that your workload can use a larger cache
size than you're giving it. You can see the amount of unused memory in the cache
by examining Qcache_free_memory .
If there are many free blocks, fragmentation is low, there are few prunes due to low
memory, and the hit rate is still low, your workload probably won't benefit much from
the query cache. Something is keeping it from being used. If you have a lot of updates,
that's probably the culprit; it's also possible that your queries are not cacheable.
If you've measured the cache hit ratio and you're still not sure whether the server is
benefiting from the query cache, you can disable it and monitor performance, then
reenable it and see how performance changes. To disable the query cache, set query
_cache_size to 0 . (Changing query_cache_type globally won't affect connections that
are already open, and it won't return the memory to the server.) You can also
 
Search WWH ::




Custom Search