7.1 Cache no lado do banco de dados
O MySQL usa algoritmos altamente escaláveis ao trabalhar com tabelas, portanto, o MySQL pode ser executado mesmo com pequenas quantidades de memória. Naturalmente, para um melhor desempenho, você precisa de mais RAM.
Para visualizar as configurações atuais, conecte-se ao banco de dados
#mysq -u root -p
mysql> show variables like 'query_cache%';
+------------------------------+-----------+
| Variable_name | Value |
+------------------------------+-----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 134217728 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+-----------+
5 rows in set (0.00 sec)
Primeiro, verifique se o cache está ativado. Variável:
query_cache_type
deve ser ON (1) ou DEMAND (2)query_cache_limit
- determina o tamanho máximo do resultado que entrará no cachequery_cache_size
ser diferente de zero. Ao usar DEMAND, apenas as solicitações que contêm a diretiva serão armazenadas em cacheSQL_CACHE;
query_cache_min_res_unit
o tamanho mínimo do bloco de memória alocado para armazenar os resultados da consulta em cache. O MySQL não armazena o cache em um grande pedaço de memória, ao invés disso ele aloca blocos com um tamanho mínimoquery_cache_min_res_unit
(=4KB por padrão) sob demanda. O último desses blocos é truncado para o tamanho dos dados e a memória restante é liberada.
O efeito do cache é que, quando o servidor recebe uma solicitação, ele verifica se o hash da solicitação está no cache. Se o hash corresponder - o servidor retorna imediatamente o resultado - sem analisar a solicitação, otimizar etc. sobrecarga - acompanhada por um mecanismo de cache - navegando no cache, gravando o resultado da consulta no cache, etc.
E se você tiver muitas solicitações pequenas no cache, isso pode levar à fragmentação da memória devido a um grande número de blocos livres. E isso, por sua vez, faz com que as entradas em cache sejam excluídas devido à falta de memória. Nesse caso, faz sentido diminuir o valor de query_cache_min_res_unit
. Se a maioria de suas consultas produzir resultados grandes, aumentar essa configuração pode melhorar o desempenho.
Vamos tentar avaliar o efeito. Observamos como os contadores de acertos do cache mudam (Qcahe_hits), o número de solicitações declaradas inválidas por falta de memória (Qcache_lowmem_prunes), o número total de solicitações do tipo SELECT (e somente elas são armazenadas em cache):
#mysq -u root -p
mysql> show status like 'Qcache%';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| Qcache_free_blocks | 715 |
| Qcache_free_memory | 130369640 |
| Qcache_hits | 24209 |
| Qcache_inserts | 16215 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 444 |
| Qcache_queries_in_cache | 1740 |
| Qcache_total_blocks | 4225 |
+-------------------------+-----------+
8 rows in set (0.00 sec)
7.2 Status atual do cache
Para monitorar o cache de consulta é usado SHOW STATUS
:
mysql> SHOW STATUS LIKE 'Qcache_%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 10 |
| Qcache_free_memory | 16755496 |
| Qcache_hits | 49812 |
| Qcache_inserts | 103999 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 180 |
| Qcache_queries_in_cache | 6 |
| Qcache_total_blocks | 28 |
+-------------------------+----------+
8 rows in set (0.00 sec)
Qcache_free_blocks
mostra quantos blocos livres existem no cache (diminuem à medida que as solicitações em cache aumentam);Qcache_total_blocks
— o número de blocos ocupados;Qcache_free_memory
- mostra a memória livre "disponível" para cache;Qcache_hits
- o número de solicitações cujos resultados foram retirados do cache, sem realmente acessar o banco de dados;Qcache_inserts
- o número de solicitações que foram adicionadas ao cache;Qcache_lowmem_prunes
- o número de solicitações que foram removidas do cache por falta de memória;Qcache_not_cached
- o número de solicitações que não foram gravadas no cache devido ao uso de funções de gerenciamento de tempo, etc.;Qcache_queries_in_cache
- o número de solicitações que estão no cache.
Você pode visualizar o número total de consultas SELECT:
mysql> show status like 'Com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 16719 |
+---------------+-------+
1 row in set (0.00 sec)
7.3 Eficiência do cache
“Recomenda-se avaliar a eficácia do cache dividindo o valor da variável Qcache_hits on Qcache_hits + Com_select
, pois ao processar uma solicitação, o contador Qcache_hits aumenta (se a solicitação for processada a partir do cache) ou Com_select (se a solicitação não for armazenada em cache). Este método é sugerido em "Mysql Performance Optimization" O'reilly
Existe outra maneira on-line
qcache_hit_ratio = qcache_hits / (qcache_hits + qcache_inserts + qcache_not_cached)
Se esse valor for > 0,8, 80% de suas solicitações serão armazenadas em cache, o que é um indicador muito bom.
Se %
o acerto do cache for baixo, você precisará aumentar o valor query_cache_size
.
O valor atual pode ser visto assim:
SHOW VARIABLES LIKE 'query_cache_size';
Novamente, surge a pergunta: como escolher um valor adequadoquery_cache_size?
Isso vai ajudar Qcache_lowmem_prunes
. Essa variável armazena o número de solicitações que foram removidas do cache devido à necessidade de armazenar novas solicitações em cache. É necessário buscar um tamanho de cache no qual Qcache_lowmem_prunes
aumentará apenas ligeiramente. Para isso, é recomendável comparar a diferença de valores Qcache_lowmem_prunes
por hora e a quantidade de requisições recebidas pelo mysql na mesma hora.
“Na prática, uma das 2 fórmulas pode ser usada para calcular query_cache_size:
query_cache_size = (number of requests for 10 minutes)*(average response volume on request) * 1,2
ou
query_cache_size = (number of requests for 10 minutes)*(average response volume on request) * 1,2
query_cache_size = (volume de tráfego em 10 minutos) * 1,2 "
Isso armazenará solicitações em cache por 10 minutos + fornecerá 20% de memória adicional para fragmentação de cache e reserva de cache adicional
Você pode calcular o número e o volume médio de uma resposta a uma solicitação usando as variáveis Bytes_sent , respectivamente
E assim query_cache_size
aumentamos os valores, depois disso você deve ficar atento aos valores Qcache_total_blocks
, Qcache_free_blocks
e Qcache_queries_in_cache
. MySQL armazena cache em blocos. Para 1 solicitação, são necessários 2 blocos: um para o próprio texto da solicitação e o segundo para o resultado.
Se considerarmos a tabela a partir do valorQcache%
Número total de blocos de cacheQcache_total_blocks – 28
A solicitação 6 está armazenada em cache agora, o que significa que 6 * 2 = 12 blocos estão ocupados
Blocos grátis Qcache_free_blocks – 10
. Quanto mais ocioso Qcache_free_blocks
, maior o grau de "fragmentação" do cache.
Se a maioria das consultas tiver uma pequena quantidade de dados resultantes, vale a pena reduzir o tamanho mínimo do bloco de cache query_cache_min_res_unit
, que é de 4 KB por padrão.
Se a maioria das solicitações retornar muitos dados, vale a pena aumentar o tamanho do bloco de cache.
O principal é atingir um valor mínimo Qcache_free_blocks
.
Se o contador Qcache_not_cached
for grande, você pode tentar aumentar a variável query_cache_limit
- isso permitirá aumentar o limite e armazenar em cache os resultados das consultas que "não cabem".
As seguintes variáveis de configuração são responsáveis pelo uso do cache de consulta:
query_cache_size
— o tamanho do cache de consulta.query_cache_size = 0
desabilita o uso do cache;query_cache_limit
- o tamanho da amostra máxima armazenada no cache;query_cache_wlock_invalidate
- determina se os dados serão retirados do cache se a tabela a qual pertencem estiver bloqueada para leitura. =
Para ativar o cache de consulta mysql, basta adicionar as seguintes linhas a my.cnf (Seção [mysqld]):
query_cache_size = 268435456
query_cache_type =1
query_cache_limit =1 048576
E reinicie o serviço.
7.4 Onde a cache não é utilizada
Não armazenado em cache:
- Pedidos de
SQL_NO_CACHE
- consultas preparadas
(Prepared statements);
- Consultas que são subconsultas da consulta externa;
- Consultas dentro de stored procedures e funções;
- Consultas que usam funções:
BENCHMARK ()
,CONNECTION_ID ()
,CONVERT_TZ ()
,CURDATE ()
,CURRENT_DATE ()
,CURRENT_TIME ()
,CURRENT_TIMESTAMP ()
,CURTIME ()
,DATABASE ()
,ENCRYPT ()
com um argumento,FOUND_ROWS ()
,GET_LOCK ()
,LAST_INSERT_ID ()
,LOAD_FILE ()
,MASTER_POS_WAIT ()
,NOW ()
,RAND ()
,RELEASE_LOCK ()
,SLEEP ()
,SYSDATE ()
,UNIX_TIMESTAMP ()
sem argumentos,USER ()
,UUID ();
- Consultas usando funções armazenadas, variáveis de usuário ou tabelas de referência em bancos de dados do sistema mysql ou INFORMATION_SCHEMA;
- • Solicitações nas seguintes formas:
SELECT ... IN SHARE MODE
SELECT ... FOR UPDATE
SELECT ... INTO OUTFILE ...
SELECT ... INTO DUMPFILE ...
SELECT * FROM ... WHERE autoincrement_col IS NULL
- Consultas com tabelas temporárias ou sem uso de tabelas;
- Solicitações geradoras de warnings (warnings);
Você pode desfragmentar o cache com o comando:
mysql>flush query cache;
Limpar - comando:
mysql>flush query cache;
O mais importante
Nunca trabalhe em produção com configurações padrão. Isso resultará na não utilização da maioria dos recursos do servidor. O ajuste adequado do MySQL pode melhorar o desempenho do banco de dados várias vezes. Isso não apenas acelerará o aplicativo, mas também lidará com uma carga pesada.
GO TO FULL VERSION