Alguém disse, algum dia que: “…invalidação de cache é uma das coisas mais terríveis em tecnologia da informação…”. Eu ouvi isso de algum guru, conhecedor do assunto, em algum evento mundo afora. A frase ficou, mas, não lembro mais o nome do dono da frase. Tudo bem, vai ver que ficou gravado no meu cache, e, quando foi invalidado não havia persistência em disco 😉

O MySQL tem vários buffers & caches. Um cara bem interessante é o MySQL Query Cache. Este cara é um cache especializado que armazena um hash das queries executadas, e frise-se, estamos falando de SELECT’s, e seus respectivos resultados.

Em outras palavras, se solicitamos ao servidor MySQL todos os clientes da cidade de São Paulo, com perfil igual a “A”, através do comando “SELECT * FROM clientes WHERE cidade = ‘São Paulo’ AND perfil = ‘A'”, o MySQL, então, armazenará um hash desta query que servirá como chave, como índice, e também, todo o resultado deste SELECT, ou seja, os clientes em questão.

Se o mesmo SELECT for enviado ao servidor; ao invés de processar tudo de novo, o MySQL, simplesmente, pegará o resultado do QC (query cache) e devolverá ao solicitante. Rápido! Fácil! Simples!

Ótimo? Hum… aí é que mora o perigo! Se estivermos falando de uma base de dados de um website, relativamente estático, será excelótimo! Agora, dependendo do grau de atualização das tabelas envolvidos, pode se tornar uma grande tragédia.

Tudo por causa da tal invalidação de cache! E que diabos é isso? Invalidação de cache é a arte 😉 de limpar, de tirar do cache dados que estão desatualizados, vencidos, expirados.

Para quem já conhece o MEMCACHED o Query Cache é muito parecido. Em ambos, você decide o que colocar no cache (verbo = cachear). No entanto, no MEMCACHED você determina um tempo de expiração, ou seja, depois de quanto tempo aquele resultado lá guardado deverá ser expirado. Até a versão 5.5 do MySQL, não há este mecanismo de expiração baseado em tempo. A expiração ocorre de forma muito mais complicada – Quando uma ou mais tabelas envolvidas no SELECT (armazenado no QC) venha a ser atualizada.

Em outras palavras se voce “cachear” resultados de SELECT’s que contenham tabelas que sofrem grande número de alterações, é possível que voce piore a performance do seu servidor, devido ao fato de o MySQL ter que armazenar o resultado de suas queries no QC, e, em seguida invalidá-los.

Em suma, o QC foi criado para aumentar a performance de seu servidor  MySQL, através da entrega rápida de resultados de queries pré-processados. O segredo todo está em escolher bem o que armazenar no query cache e o que não armazenar. E isto vale para qualquer tipo de cache (inclusive, e, principalmente, para o MEMCACHED).

Existem vários relatos de clientes que me reportam que depois de terem ativados o Query Cache, passaram a experimentar uma grande queda de performance. Reposta, uso indevido.

É por isso que sou contra os blogs & how-to’s que existem aos kilos na internet. Eles mostram como ativar e/ou instalar determinadas funcionalidades/programas. Mas, dificilmente, explicam o conceito. E a falta deste conceito é que nos leva rumo contrário ao santo graal da performance.

Num exemplo prático. Imaginem um sistema de vendas via internet. Quais tabelas cachear, quais não cachear, e o que precisar ser visto com carinho:

a/ Cachear: cidades, estados, formas de pagamento, promoções, ranking de produtos*, ranking de clientes*, produtos;

b/ Não cachear: orçamentos, pedidos (carrinho de compras), movimentação de estoque;

c/ Pensar com carinho: clientes

Ranking de Produtos/Clientes, normalmente, são tarefas (SELECT’s) que precisam varrer um série de tabelas, e, normalmente, vai de “full scan table”. Isto demora, e, é pesado. Aí entra a tal da tabela sumarizada e os eventos.

Cria-se um evento para rodar, digamos, de hora em hora, e atualizar as tabelas sumarizadas de Ranking de Produtos e Clientes. Como isto só atualiza de hora/hora, faz sentido que os SELECT’s contra estas tabelas (ou tipo de tabelas) sejam cacheados.

Normalmente, quando ministro o curso de PT (Performance Tuning) ou de MEMCACHED + MySQL eu sempre digo o seguinte: “Cacheiem tudo que custa caro para processar, mas, nunca se esqueçam das demais técnicas de performance”. Tabelas sumarizadas, são um bom exemplo disso, pois unem duas técnicas de performance: sumarização e cache.

Num próximo artigo, vamos discutir a configuração do Query Cache.