Forums » PHP e MySQL

Otimizando consultas MySQL com o Memcached

  • 8 de março de 2017 19:23:33 ART

    Otimizando consultas MySQL com o Memcached

    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:

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

    É 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.

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

    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:

      <?php
       
      $mem = new Memcache;
      $mem->addServer($_SERVER['HTTP_HOST']);
       
      $sql = "SELECT * FROM `noticias` WHERE `ativa` = 1 ORDER BY `data` DESC";
      $chave = md5($sql);
       
      // Buscamos o resultado na memória
      $cache = $mem->get($chave);
       
      // Verifica se o resultado não existe ou expirou
      if ($cache === false) {
      // Executa a consulta novamente
      $query=mysql_query($sql);
       
      $tempo=60*60; // 3600s
      $mem->set($chave, $query, 0, $tempo);
      } else {
      // A consulta está salva na memória ainda, então pegamos o resultado:
      $query=$cache;
      }
       
      // Exibição dos dados
      while ($dados = mysql_fetch_assoc($query)) {
      // Aqui você faz a exibição de cada notícia
      }

    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:

      <?php
      function mysql_queryCache($consulta, $tempo = 3600) {
      $chave=md5($consulta);
       
      $mem=newMemcache;
      $mem->addServer($_SERVER['HTTP_HOST']);
       
      $query=$mem->get($chave);
      if ($query===false) {
      $query=mysql_query($consulta);
      $mem->set($chave, $query, 0, $tempo);
      }
       
      return$query;
      }

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

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

    Este post foi editado por Maria das Dores Socoro Pinto em 8 de março de 2017 19:25:56 ART"