Сайт поддержки администраторов САР, у нас вы можете скачать скрипты буксов, ферм и т.д, а также обсудить все это на форуме

Кешируем SQL запросы

Кешируем SQL запросы
Пример использования кеша...

И так, стандартный запрос допустим вывода новостей выглядит так
<?
$sql="select * from tb_news order by id desc limit 1";
$res=mysql_query($sql);
$row=mysql_fetch_array($res);

echo $row["data"];
echo $row["newstext"];
?>

Ничего особого, постоянная нагрузка на MySQL, ну да ладно.

Теперь покажу как выглядит мой запрос (именно кеш):
<?
$sql="select * from tb_news order by id desc limit 1";
$res=new MySQLCache($sql, 300); // 300 это секунды кеша
$row=$res->fetch_assoc();

echo $row["data"];
echo $row["newstext"];
?>

Теперь объясняю в чем суть, если кто-то не понял.

В стандартном запросе мы имеем эту хрень (так понятней все будет):

$res=mysql_query($sql);
$row=mysql_fetch_array($res);

А в моем же мы имеем это:
$res=new MySQLCache($sql, 300); // 300 это секунды кеша
$row=$res->fetch_assoc();

Убран постоянный запрос к базе и выполнения операции намного стало быстрей.

Но для этого нужно подключить класс. И так, для начала поставьте этот инклуд в header.php:
include("cache_sql.php");

Предварительно создав сам файл.

И засунуть туда этот код для работы кеша:
<?php
class MySQLCache{
   var $CachePath = 'cache_data/'; //Папка куда будет записываться кеш запросов
   var $PeakFilename = 'speed_site.log'; //Логистика (Скорость дата)
   var $Debug = true;
   var $FromCache = false;
   var $DataDate = 0;
   var $errno = 0;
   var $error = '';
   var $Peak = array
   (
      0,
      '',
      '',
      '',
   );
   var $NextRowNo = 0;
   var $ResultData = array
   (
      'fields' => array(),
      'data' => array(),
   );
   function MySQLCache($query, $valid = 10)
   {
      if ($this->CachePath == '')
      {
         $this->CachePath = dirname(__FILE__);
      }
      $query = trim($query);

      //if (!eregi('^SELECT', $query))
      //{
      //return mysql_query($query);
      //}

      $filename = $this->CachePath . '/' . md5($query) . '.txt';
      if ((@$file = fopen($filename, 'r')) && filemtime($filename) > (time() - $valid))
      {
         flock($file, LOCK_SH);
         $serial = file_get_contents($filename);
         $this->ResultData = unserialize($serial);
         $this->DataDate = filemtime($filename);
         $this->FromCache = true;
         fclose($file);
         return true;
      }
      if ($file)
      {
         fclose($file);
      }
      $time_start = microtime(true);
      @ $SQLResult = mysql_query($query);
      $time_end = microtime(true);
      $this->DataDate = time();
      $time_exec = $time_end - $time_start;
      if (!$SQLResult)
      {
         if ($this->Debug)
         {
            die('Error from query "' . $query . '": ' . mysql_error());
         }
         else
         {
            $this->errno = mysql_errno();
            $this->error = mysql_error();
            return false;
         }
      }
      $peak_filename = $this->CachePath . '/' . $this->PeakFilename;
      if (@$file = fopen($peak_filename, 'r'))
      {
         flock($file, LOCK_SH);
         $fdata = file($peak_filename);
         foreach ($fdata as $key => $value)
         {
            $this->Peak[$key] = trim($value);
         }
         $this->Peak[0] = floatval($this->Peak[0]);
      }
      if ($file)
      {
         fclose($file);
      }
      if ($time_exec > $this->Peak[0])
      {
         $this->Peak = array
         (
            $time_exec,
            date('r'),
            $query,
            $_SERVER['SCRIPT_FILENAME'],
         );
         $file = fopen($peak_filename, 'w');
         flock($file, LOCK_EX);
         fwrite($file, implode("n", $this->Peak));
         fclose($file);
      }
      $nf = mysql_num_fields($SQLResult);
      for ($i = 0; $i < $nf; $i++)
      {
         $this->ResultData['fields'][$i] = mysql_fetch_field($SQLResult, $i);
      }
      $nr = mysql_num_rows($SQLResult);
      for ($i = 0; $i < $nr; $i++)
      {
         $this->ResultData['data'][$i] = mysql_fetch_row($SQLResult);
      }
      $file = fopen($filename, 'w');
      flock($file, LOCK_EX);
      fwrite($file, serialize($this->ResultData));
      fclose($file);
      return true;
   }
   function num_fields()
   {
      return sizeof($this->ResultData['fields']);
   }
   function field_name($num)
   {
      if (isset($this->ResultData['fields'][$num]))
      {
         return $this->ResultData['fields'][$num]->name;
      }
      else
      {
         return false;
      }
   }
   function fetch_field($num)
   {
      if (isset($this->ResultData['fields'][$num]))
      {
         return $this->ResultData['fields'][$num];
      }
      else
      {
         return false;
      }
   }
   function field_len($num)
   {
      if (isset($this->ResultData['fields'][$num]))
      {
         return $this->ResultData['fields'][$num]->max_length;
      }
      else
      {
         return false;
      }
   }
   function field_type($num)
   {
      if (isset($this->ResultData['fields'][$num]))
      {
         return $this->ResultData['fields'][$num]->type;
      }
      else
      {
         return false;
      }
   }
   function field_flags($num)
   {
      if (!isset($this->ResultData['fields'][$num]))
      {
         return false;
      }
      $result = array();
      if ($this->ResultData['fields'][$num]->not_null)
      {
         $result[] = 'not_null';
      }
      if ($this->ResultData['fields'][$num]->primary_key)
      {
         $result[] = 'primary_key';
      }
      if ($this->ResultData['fields'][$num]->unique_key)
      {
         $result[] = 'unique_key';
      }
      if ($this->ResultData['fields'][$num]->multiple_key)
      {
         $result[] = 'multiple_key';
      }
      if ($this->ResultData['fields'][$num]->blob)
      {
         $result[] = 'blob';
      }
      if ($this->ResultData['fields'][$num]->unsigned)
      {
         $result[] = 'unsigned';
      }
      if ($this->ResultData['fields'][$num]->zerofill)
      {
         $result[] = 'zerofill';
      }
      if ($this->ResultData['fields'][$num]->binary)
      {
         $result[] = 'binary';
      }
      if ($this->ResultData['fields'][$num]->enum)
      {
         $result[] = 'enum';
      }
      if ($this->ResultData['fields'][$num]->auto_increment)
      {
         $result[] = 'auto_increment';
      }
      if ($this->ResultData['fields'][$num]->timestamp)
      {
         $result[] = 'timestamp';
      }
      return implode(' ', $result);
   }
   function num_rows()
   {
      return sizeof($this->ResultData['data']);
   }
   function fetch_row()
   {
      if (($this->NextRowNo+1) > $this->num_rows())
      {
         return false;
      }
      $this->NextRowNo++;
      return $this->ResultData['data'][$this->NextRowNo - 1];
   }
   function fetch_assoc()
   {
      if (($this->NextRowNo + 1) > $this->num_rows())
      {
         return false;
      }
      for ($i = 0; $i < $this->num_fields(); $i++)
      {
         $result[$this->ResultData['fields'][$i]->name] =
            $this->ResultData['data'][$this->NextRowNo][$i];
      }
      $this->NextRowNo++;
      return $result;
   }
}
?>

И создать папку под названием cache_data и CMOD 777 на нее.

Ну вот и все вроде... Пользуйтесь на здоровье...


Рубрика: Информация » Программирование   |   Автор: kirill   |   Просмотры: 5088
Комментариев: 216
Публикаций: 14
ICQ: 207679
  Автор: vlaf   |   Группа: Пользователи   |   Дата: 29 июля 2011  
Сильно увеличивает скорость обработки запроса?
Комментариев: 731
Публикаций: 50
ICQ: --
  Автор: Green-wm   |   Группа: Пользователи   |   Дата: 29 июля 2011  
Цитата: VLAF
Сильно увеличивает скорость обработки запроса?

Если знаешь что такое кэшь - то думаю понимаешь сильно или нет.
Комментариев: 216
Публикаций: 14
ICQ: 207679
  Автор: vlaf   |   Группа: Пользователи   |   Дата: 29 июля 2011  
что такое кэшь знаю winked . значит увеличит)
Комментариев: 162
Публикаций: 19
ICQ: 553069709
  Автор: ZKolyaNZ   |   Группа: Модераторы   |   Дата: 29 июля 2011  
Короче по ходу уменьшет нагрузку на MySQL , наверное ещё и быстродействие улудшится))
кстати таким методом можна весь скрипт переделать , так как вывод рекламы вопще тормозит работу.
на обычном sooofast реклама выводится в 8-15 SQL плюс к этому же 10 конектов, то есть , если одновременно на гамно-хостинге iphoster зайти 1000 людям , то положиться хостинг.
Комментариев: 64
Публикаций: 8
ICQ: 959098
  Автор: kirill   |   Группа: Программисты   |   Дата: 29 июля 2011  
Цитата: ZKolyaNZ
Короче по ходу уменьшет нагрузку на MySQL , наверное ещё и быстродействие улудшиться))кстати таким методом можна весь скрипт переделать , так как вывод рекламы вопще тормозит работу.на обычном sooofast реклама выводится в 8-15 SQL плюс к этому же 10 конектов, то есть , если одновременно на гамно-хостинге iphoster зайти 1000 людям , то положеться хостинг.


Можно и будет клева работать даже можно сделать прикол))
Закинуть базу в кеш на 100 лет и удалить реальную базу)))) шучу)))
Смотрите не переборщите только !!))

Старался как проше сделать кеш
Комментариев: 162
Публикаций: 19
ICQ: 553069709
  Автор: ZKolyaNZ   |   Группа: Модераторы   |   Дата: 29 июля 2011  
kirill,

Да я понял )
Да в принципе не плохо с объектами в php умеешь работать )
Комментариев: 64
Публикаций: 8
ICQ: 959098
  Автор: kirill   |   Группа: Программисты   |   Дата: 29 июля 2011  
Вы ещё мою CMS не видели)) скоро выйдет надеюсь)))

по шустрей работает чем DLE джумла ворд пресс и тогда лее))
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 29 июля 2011  
А memcached уже не в моде?
Комментариев: 129
Публикаций: 9
ICQ: 646895
  Автор: SpawN   |   Группа: Дизайнеры   |   Дата: 29 июля 2011  
no какойто старый способ совсем
Комментариев: 64
Публикаций: 8
ICQ: 959098
  Автор: kirill   |   Группа: Программисты   |   Дата: 29 июля 2011  
Цитата: VELIK505
А memcached уже не в моде?


Мне не понравилась

Цитата: SpawN
какойто старый способ совсем


Да нет не сильно старый но за то самый надежный)
Или мозги у меня старые)))
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 29 июля 2011  
Просто ты не разобрался а не непонравилось тебе. Работает раз в 15 быстрее такого способа
Комментариев: 118
Публикаций: 2
ICQ: 819374
  Автор: Rufus   |   Группа: Программисты   |   Дата: 29 июля 2011  
Ребята, скажу вам на будующее - SQL сервер писали не идиоты... Там и так есть кеширование своеобразное.
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 29 июля 2011  
В мускуле есть микро кеш запросы которые выполнялись база повтороно может не выполнять а просто отдавать
Комментариев: 73
Публикаций: 18
ICQ: 634377420
  Автор: BeerMan   |   Группа: Пользователи   |   Дата: 30 июля 2011  
так что лучше его не ставить???
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 30 июля 2011  
Лучше не ставить. Почитай как включить кеширование БД. Хотя оно почти на всех хостах уже включено. Лучше xcache поставь
Комментариев: 73
Публикаций: 18
ICQ: 634377420
  Автор: BeerMan   |   Группа: Пользователи   |   Дата: 30 июля 2011  
а об етом чтото знаешь??
@ob_start("ob_gzhandler");
@ob_end_flush();
Комментариев: 218
Публикаций: 6
ICQ: 573235722
  Автор: VELIK505   |   Группа: Программисты   |   Дата: 31 июля 2011  
Знаю конечно пережимает исходный код перед выводом в поток.

и не только.
Комментариев: 13
Публикаций: 2
ICQ: 521839
  Автор: master   |   Группа: Пользователи   |   Дата: 31 июля 2011  
Прикольная штуковина Ресспект и уважуха автору.
Комментариев: 64
Публикаций: 8
ICQ: 959098
  Автор: kirill   |   Группа: Программисты   |   Дата: 31 июля 2011  
Цитата: master
Прикольная штуковина Ресспект и уважуха автору.

Спс)
Комментариев: 90
Публикаций: 2
ICQ: 656527
  Автор: NGS   |   Группа: Пользователи   |   Дата: 07 августа 2011  
$res=new MySQLCache($sql, 300); // 300 это секунды кеша
$row=$res->fetch_assoc();...

Тоесть для каждого запроса к БД ты создаешь новый класс???
спрашивается НАХРЕНА?

тьфу не класс, а обьект

а так вприципе для вывода Новостей, статичных ссылок, ратора - вприцнипе подойдет отлично!
Комментариев: 64
Публикаций: 8
ICQ: 959098
  Автор: kirill   |   Группа: Программисты   |   Дата: 07 августа 2011  
Цитата: NGS
а так вприципе для вывода Новостей, статичных ссылок, ратора - вприцнипе подойдет отлично!

а я для этого и сделал =))) более только за бюджет)))
Комментариев: 75
Публикаций: 2
ICQ: 50406060
  Автор: Contego   |   Группа: Пользователи   |   Дата: 04 ноября 2011  
при хорошей оптимизации скрипт делает только хуже.
было: Страница сгенерирована за 0.007 секунд в среднем, после создания такого кеша стало: 0.218254 секунд, 0.041976 секунд, 0.018141 секунд, 0.009636 секунд, 0.012751 секунд
+ статистика получается не в онлаин обновляется.

т.е. на мой скрипт оптимизация не дала ожидаемых результатов.. терь заипешься выковыривать:(
Комментариев: 63
Публикаций: 10
ICQ: --
  Автор: Hitman   |   Группа: Пользователи   |   Дата: 27 апреля 2012  
Я тут новичок…. Объясните полную ее работу и как правильно поставить без кривизны…
Информация

Посетители, находящиеся в группе Гости, не могут оставлять комментарии к данной публикации.