Até recentemente, eu via o cache de consulta como uma ferramenta muito importante para melhorar o desempenho da consulta. Hoje, eu estava ouvindo um podcast que discutia o ajuste do cache de consulta para 0 e o uso de uma solução de cache de memória melhor (como memcache.d).
Mas eles também mencionaram que há alguns casos em que query_cache é útil. Portanto, uma recomendação geral seria habilitá-lo sob demanda (usando SELECT SQL_CACHE
, com uma configuração query_cache_type = 2).
Minha pergunta é, supondo que você tenha uma solução de cache como memcache.d, que tipo de circunstâncias tornaria query_cache mais ideal?
Editar: link adicionado
Acho que há muitas informações erradas sobre o cache de consulta por aí.
O melhor caso para o cache de consulta é quando você precisa examinar um número muito grande de linhas, mas retornar apenas algumas para um cliente. Uma situação típica em que isso é comum é um sistema em que nenhuma otimização ou indexação adequada foi aplicada.
Em uma situação em que muitas das consultas são pesquisas de chave primária ou muito bem otimizadas, o cache de consulta pode causar escalabilidade negativa. Sim: piora as coisas!
A razão para isso é que o design adiciona algum bloqueio interno, o que limita o dimensionamento do servidor MySQL em máquinas com vários núcleos.
O cache de consulta é a causa de muitas "paralisações repentinas" no MySQL - nem todas óbvias. No Percona Server, adicionamos um novo estado à lista de processos (Waiting on Qcache mutex): http://www.percona.com/docs/wiki/percona-server:features:status_wait_query_cache_mutex
(Isenção de responsabilidade, eu trabalho para a Percona.)
Memcached (ou Coherence ) armazena em cache conjuntos de resultados inteiros . Um cache no banco de dados armazena em cache as linhas do banco de dados. Então, digamos que você tenha um padrão de acesso em que a consulta é fixa e os dados são alterados com pouca frequência (por exemplo
select * from restaurants where location='london'
, ). Você pode executar essa consulta milhares de vezes sempre que um novo restaurante é adicionado, portanto, armazenar em cache todo o conjunto de resultados faz sentido, pois evita ir ao banco de dados todas as vezes - mas você ainda tem toda a capacidade de gerenciamento e flexibilidade do RDBMS e do SQL (você só precisa expulsar o cache nas ocasiões em que os dados forem alterados). Algumas pessoas chamam isso de dados de referência ou dados estáticos.Mas digamos que você tenha um padrão de acesso ad hoc (talvez haja muitas opções para seu usuário encontrar exatamente onde deseja comer esta noite, mas é raro dois usuários terem exatamente as mesmas preferências). Em seguida, você pode querer armazenar em cache as linhas (para evitar ir para o disco), mas montar cada conjunto de resultados dinamicamente na memória. É quando você deseja que o próprio banco de dados gerencie o que e como ele armazena em cache. Na maioria dos casos, uma abordagem híbrida ou em camadas funcionará melhor.
Observe que há também um terceiro tipo de cache em ação - o cache do sistema de arquivos do sistema operacional. Eu não gosto disso, pela simples razão de que se você ler um bloco do disco, ele agora existe no cache do banco de dados e no cache do sistema de arquivos, mas o banco de dados não "sabe" sobre o último, então não pode faça algo inteligente com ele, como ver com que frequência ele é usado. Do ponto de vista do DBA, qualquer memória sobressalente no sistema sobre o que o próprio sistema operacional precisa para ser feliz é desperdiçada.
Não acho que já tenha sido mencionado aqui, mas é possível que o cache de consulta também tenha um efeito adverso no desempenho; talvez seja isso que foi mencionado em seu podcast. Se a eficiência do cache de consulta for baixa (
Qcache_hits / (Qcache_hits + Com_select)
) e houver muitas podas de cache de consulta (Qcache_lowmem_prunes/Uptime
) ocorrendo, é possível que a sobrecarga de manutenção do cache esteja custando mais do que você ganha.Este post de Peter Zaitsev cobre as coisas com um pouco mais de detalhes. Ao contrário de algumas respostas aqui, ele afirma que o cache é para conjuntos de resultados inteiros. No entanto, o post tem vários anos. Alguns pensamentos mais recentes foram postados em abril.
Sempre tive a impressão de que ele está armazenando em cache conjuntos de resultados completos, não linhas como mencionado acima. Se você tiver exatamente a mesma consulta, ela ignorará a análise/planejamento e retornará o mesmo conjunto de resultados (cujo tamanho máximo é controlado por
query_cache_limit
).Se você tiver o cache de consulta desabilitado, então um ambiente de alta leitura onde os SELECTs são muito simples, então não há mecanismos de bloqueio habilitados. Recentemente experimentei isso com o MySQL 5.5 usando Multiple Buffer Pools.
Se você chamar as mesmas consultas básicas repetidamente, não será necessário analisar a mesma consulta repetidamente até que as vacas voltem para casa. Um pequeno cache de consulta deve ser suficiente em um ambiente de leitura pesado usando um pequeno conjunto de SELECTs que você sabe que sempre serão chamados.
memcached é muito mais útil para grandes conjuntos de dados em ambiente de leitura pesada. O cache de consulta é um pato manco nesse ponto.