Forums » PHP e MySQL

Otimizando consultas MySQL com o Memcached

    • 466 posts
    25 de dezembro de 2013 08:19:59 ART

    Otimizando consultas MySQL com o Memcached

    Reparei que muita gente tem procurado sobre otimização de sites e segurança, então vou tentar focar sobre esses dois assuntos essa semana.

    Hoje falarei sobre o Memcached, um recurso indispensável para servidores que rodam sites pesados. A funcionalidade principal dele consiste em armazenar “qualquer coisa” na memória (RAM) do servidor para uso posterior. Segundo o site do próprio, ele é “um sistema distribuído de alto desempenho para o cacheamento (armazenamento) de objetos na memória, genérico por natureza, mas feito para aumentar a velocidade de sites dinâmicos, diminuindo a carga sobre o banco de dados”.

    Quando usar o Memcache?

    Suponhamos que você tenha um site que faz várias e várias consultas ao MySQL para exibir uma página e, algumas delas, demoram mais de 1 seguro para ser executada… Isso significa que o seu site não está otimizado e, obviamente, está mais lento do que poderia ser.

    A maioria dos servidores – de qualidade – hoje em dia, já vêm com ele instalado… Caso você precise instalar ele no seu, recomendo dar uma olhada no site oficial para maiores detalhes.

    Vou mostrar pra vocês como armazenar uma consulta na memória e depois pegar esses dados, sem precisar executar a query novamente… Vale lembrar que só vale a pena usar o Memcached para consultas que pesam no seu sistema, pois foi pra esse propósito que ele foi feito.

    Consulta simples

    Normalmente você faria uma consulta assim:

    1 <?php
    2  
    3 $sql = "SELECT * FROM `noticias` WHERE `ativa` = 1 ORDER BY `data` DESC LIMIT 0, 20";
    4 $query = mysql_query($sql);
    5 while ($dados = mysql_fetch_assoc($query)) {
    6     // Aqui você faz a exibição de cada notícia
    7 }
    8  
    9 ?>

    É uma consulta normal que, nesse exemplo, não deve pesar muito… Mas imaginemos que essa consulta demore uns 2~3 segundos para ser executada.

    Armazenando o resultado na memória com o Memcached

    Este exemplo irá armazenar o resultado da consulta na memória, durante 1 hora… No próximo bloco mostrarei como verificar se há um resultado armazenado na memória antes de executar a consulta novamente.

    01 <?php
    02  
    03 // Inicia o Memcache
    04 $mem = new Memcache;
    05 // Define qual o servidor que se está usando
    06 $mem->addServer($_SERVER['HTTP_HOST']);
    07  
    08 $sql = "SELECT * FROM `noticias` WHERE `ativa` = 1 ORDER BY `data` DESC";
    09 $query = mysql_query($sql);
    10  
    11 // Criamos uma chave para a consulta, baseada no MD5 dela
    12 $chave = md5($sql);
    13 // A consulta ficará armazenada por 1 hora
    14 $tempo = 60 * 60; // 3600s
    15 // Salvamos o resultado na memória
    16 $mem->set($chave, $query, 0, $tempo);
    17  
    18 // Exibição dos dados
    19 while ($dados = mysql_fetch_assoc($query)) {
    20     // Aqui você faz a exibição de cada notícia
    21 }
    22  
    23 ?>

     

    Consulta otimizada com o Memcached

    Agora que já sabemos como armazenar o resultado na memória, podemos fazer uma verificação e só executar a consulta sempre que o resultado expirar ou não existir, dessa forma:

    01 <?php
    02  
    03 $mem = new Memcache;
    04 $mem->addServer($_SERVER['HTTP_HOST']);
    05  
    06 $sql = "SELECT * FROM `noticias` WHERE `ativa` = 1 ORDER BY `data` DESC";
    07 $chave = md5($sql);
    08  
    09 // Buscamos o resultado na memória
    10 $cache = $mem->get($chave);
    11  
    12 // Verifica se o resultado não existe ou expirou
    13 if ($cache === false) {
    14     // Executa a consulta novamente
    15     $query = mysql_query($sql);
    16  
    17     $tempo = 60 * 60; // 3600s
    18     $mem->set($chave, $query, 0, $tempo);
    19 } else {
    20     // A consulta está salva na memória ainda, então pegamos o resultado:
    21     $query = $cache;
    22 }
    23  
    24 // Exibição dos dados
    25 while ($dados = mysql_fetch_assoc($query)) {
    26     // Aqui você faz a exibição de cada notícia
    27 }
    28 ?>

     

    Função de atalho para o Memcache

    Você ainda poderia fazer uma função para fazer todo esse trabalho por você… Ficaria mais ou menos assim:

    01 function mysql_queryCache($consulta, $tempo = 3600) {
    02     $chave = md5($consulta);
    03  
    04     $mem = new Memcache;
    05     $mem->addServer($_SERVER['HTTP_HOST']);
    06  
    07     $query = $mem->get($chave);
    08     if ($query === false) {
    09         $query = mysql_query($consulta);
    10         $mem->set($chave, $query, 0, $tempo);
    11     }
    12  
    13     return $query;
    14 }

    E agora, o exemplo anterior usando a função:

    01 <?php
    02  
    03 $sql = "SELECT * FROM `noticias` WHERE `ativa` = 1 ORDER BY `data` DESC";
    04 $query = mysql_queryCache($sql);
    05  
    06 // Exibição dos dados
    07 while ($dados = mysql_fetch_assoc($query)) {
    08     // Aqui você faz a exibição de cada notícia
    09 }
    10 ?>

    Espero que tenham gostado! :)