Сделал тут кеширование Sql запросов, быстрее работать скажем прямо не стало, хотя мб запрос простой и таблица маленькая, но всёже, а зачем оно - кеширование sql запросов? сам класс PHP: <? class db { private $link,$cache_dir,$lastident; public $pref=false; public $sqls,$insert_id,$afectrows,$lastquery; public static $cnf; private $CacheProc=array(); private $Cacher=array(); private $CacheResource=array(); function __construct() { if (!self::$cnf) trigger_error("Ошибка: Не установлена переменная с конфигурациями \$cnf",E_USER_ERROR); $this->link = mysql_connect(self::$cnf['db_host'],self::$cnf['db_user'],self::$cnf['db_pass']) or $this->debug("Ошибка при подключении","Кофигурации:\r\n".print_r($cnf,1)); if (self::$cnf['db_encode']) mysql_query('SET NAMES '.self::$cnf['db_encode']); mysql_select_db(self::$cnf['db_name'],$this->link); $this->pref=self::$cnf['db_pref']; } /* Делает Запрос в БД $sql - текст запроса $ident - идент кеша, если кешируем зы. возвращает либо ресурс если нет кеша, либо идент кеша */ function Query($sql,$ident=false){ if($ident) { if($this->is_cache($ident)) { $this->NumRows=true; return $ident; } } $this->sqls++; $sql=str_replace(array("?p","?P"),$this->pref,$sql); $this->lastquery=$sql; $sql=mysql_query($sql) or $this->debug("Ошибка при выполнении Sql запроса в методе Query","Запрос: ".$this->lastquery); $this->lastident[$this->sqls]=$ident; // ключем лучше сделать ID ресурса return $sql; } /* Возвращает массив с результатами $result - ресурс запроса или идент кеша $cache_on - Включит кеш только для этого запроса, даже если в настройках кеширование отключено */ function Fetch_array($result,$cache_on=0){ $arr=array(); // по дефолту вернём array() if(is_resource($result)) { // если ресурс $arr=mysql_fetch_assoc($result); // получаем массив if($cache_on || self::$cnf['cache_on']) // если кеширование включено $this->CacheProc[$this->lastident[$this->sqls]][]=$arr; // кешируем, пока в переменную }else { // а если не ресурс if(empty($this->CacheResource)) $this->CacheResource=$this->CacheQuery($result); // делаем запрос кеша if($this->CacheResource){ $arr=$this->CacheResource[0]; // берём первый элемент из кеша unset($this->CacheResource[0]); // удаляем его в кеше $this->CacheResource=array_values($this->CacheResource); // обновляемся } } return $arr; } function Result($result) { return mysql_result($result,0); } function Result_query($sql) { $sql=$this->query($sql); if ($sql) return $this->result($sql); return false; } /* Вернёт массив с результатами запроса $sql */ function Super_query($sql,$ident=false,$cache_on=0) { if($res=$this->CacheQuery($ident)) return $res; $res=array(); $sql=$this->query($sql); while($row=$this->fetch_array($sql)) { $res[]=$row; } if($ident && ($cache_on || self::$cnf['cache_on'])) $this->CacheProc[$ident]=$res; return $res; } function Inset_id() { return $this->insert_id; } function NumRows($sql) { if(is_resource($sql)) return mysql_num_rows($sql); else return true; } function Afectrows() { return $this->afectrows; } function SqlGetAllRows($table,$where=1) { return $this->result_query("SELECT COUNT(*) FROM `{$this->pref}_$table` WHERE $where"); } function SqlGetOneRow($table,$row,$where=1) { return $this->result_query("SELECT `$row` FROM `{$this->pref}_$table` WHERE $where"); } function SqlGetLine($table,$line,$where=1) { return $this->fetch_array( $this->query("SELECT `$line` FROM `{$this->pref}_$table` WHERE $where LIMIT 1") ); } function SqlGetLines($table,$where=1) { return $this->fetch_array( $this->query("SELECT * FROM `{$this->pref}_$table` WHERE $where LIMIT 1") ); } function SqlGetAllLines($table,$where=1) { return $this->super_query("SELECT * FROM `{$this->pref}_$table` WHERE $where"); } function InsertInto($table,$value) { $ident=false; if (!is_array($table) && is_array($value[0])) { $values=''; for($i=0,$c=count($value);$i<$c;$i++) { $values.="("; $in=''; foreach($value[$i] as $key=>$val) { if (is_string($key)) $in.="`$key`,"; $values.="'".mysql_real_escape_string($val)."',"; } $values=substr($values,0,-1); $values.="),"; if ($in) $in="(".substr($in,0,-1).")"; } $values=substr($values,0,-1); $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` ".$in." VALUES ".$values); }else if (!is_array($table) && is_array($value)) { $values='';$in=''; foreach($value as $key=>$val) { $values.="'".mysql_real_escape_string($val)."',"; if (is_string($key)) $in.="`$key`,"; } $values=substr($values,0,-1); $values="($values)"; if ($in) $in="(".substr($in,0,-1).")"; $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` ".$in." VALUES ".$values); }else if(!is_array($table) && !is_array($value)) { $ident=$this->query("INSERT INTO `".$this->pref."_".$table."` VALUES ($value)"); } $this->afectrows=mysql_affected_rows(); return $ident; } function Update($table,$value,$where=0) { $ident=false; if (!is_array($table) && !is_array($value)) { $ident=$this->query("UPDATE ".$this->pref."_".$table." SET ".$value." ".($where?"WHERE $where":"")); }else if (!is_array($table) && is_array($value)) { $sql="UPDATE ".$this->pref."_".$table." SET "; for($i=0,$c=count($value);$i<$c;$i++) { $sql.="{$value[$i]}".($i!==$c-1?",":""); } if ($where) $sql.=" WHERE $where"; $ident=$this->query($sql); } $this->afectrows=mysql_affected_rows(); return $ident; } function Del($table,$value) { $ident=false; if (!is_array($table) && !is_array($value)) { $ident=$this->query("DELETE FROM ".$this->pref."_".$table." WHERE ".$value); }else if (!is_array($table) && is_array($value)) { $sql="DELETE FROM ".$this->pref."_".$table." WHERE "; for($i=0,$c=count($value);$i<$c;$i++) { $sql.=$value[$i].($i!==$c-1?" OR ":""); } } $this->afectrows=mysql_affected_rows(); return $ident; } function Delet($table,$value) { return $this->Del($table,$value); } function debug($msg,$upinfo='') { print " <h4>$msg</h4> <hr> <b>MysqlError:</b>".(!mysql_error()?"None":mysql_error())."<br> <b>Errorno:</b>".(mysql_errno()?mysql_errno():"None")." ".($upinfo?"<hr><b>Дополнительно:</b><br><textarea cols=70 rows=7>$upinfo</textarea>":"")." "; exit; } /* Вернёт папку с кешем */ private function GetCacheDir($ident) { if (!$this->cache_dir[$ident]) $this->cache_dir[$ident]=$_SERVER['DOCUMENT_ROOT']."/".self::$cnf['cache_dir'].'/'.md5($ident).".sql.php"; return $this->cache_dir[$ident]; } /* Запрос кеша по иденту, вернёт массив с результатами как при super_query или false в случае неудачи */ function CacheQuery($ident) { if(!$ident) return false; $file=$this->GetCacheDir($ident); if($this->is_cache($ident)){ if(!$this->Cacher[$ident]){ include $file; $this->Cacher[$ident]=$__ARRAY; } return $this->Cacher[$ident]; }else { if(file_exists($file)) unlink($file); } return false; } /* Жив ли ещё кеш? */ function CacheLifeEnd($ident){ if(time()-filemtime($this->GetCacheDir($ident))<=self::$cnf['cache_time']) return false; return true; } /* Существует ли кеш? */ function is_cache($ident) { $file=$this->GetCacheDir($ident); if(file_exists($file) && !$this->CacheLifeEnd($ident)) return true; return false; } /* Сохраняет кеш в файлы */ private function CacheSave() { if($this->CacheProc) { foreach($this->CacheProc as $ident=>$arr) { $filedir=$_SERVER['DOCUMENT_ROOT']."/".self::$cnf['cache_dir']."/".md5($ident).".sql.php"; @file_put_contents( $filedir, "<? \$__ARRAY=".$this->FormArray($arr)."?".">") or $this->debug("Ошибка, Не могу сохранить файл с кешем", "FileDir:$filedir\r\nFileIdent:$ident"); } } } private function FormArray($arr) { $res=array(); if(empty($arr)) return "array()"; foreach($arr as $key=>$val) { if(!is_array($val)){ $res[]="\"$key\"=>\"$val\""; } else { $res=array_merge($res,array($this->FormArray($val))); } } return "array(".implode(",",$res).")"; } function __destruct() { $this->CacheSave(); } } db::$cnf=array( "db_name"=>"test", "db_user"=>"root", "db_pass"=>"", "db_host"=>"localhost", "db_encode"=>"cp1251", "db_pref"=>"test", "cache_time"=>"60", "cache_dir"=>"sqlcache", "cache_on"=>0, ); // Настройки $db=new db(); $sql=$db->query("SELECT * FROM ?p_test","somesql"); $res=array(); if($db->numrows($sql)) { // если чёто вернулось while($row=$db->fetch_array($sql,1)) { // получаем инфу их кеша или из БД $res[]=$row; } print_r($res); }else { print "Stop Stop"; } ?>
Смысл кеша в сложных запросах, которые ребуют сложных пересечений, выполняются достаточно часто, но при этом, данные меняются достаточно редко.
Mr.M.I.T. В MySQL есть кеш запросов. Имеет смысл делать кеш не запросов, а уже сформированных кусков данных или всей страницы целиком.
Это другая тема =) ну вот тут Олег сказал, что имеет смысл делать кеш только сложных запросов, пожалуй это всё что я хотел услышать =)) А по теме кеша в мускуле, не знаю какой он там, но некоторый запросы по секунде, заставляют задуматься... А кстати, какая функция возвращает id mysql ресурса или что-то в этом роде...
не изобретайте кривой трехколесный велосипед. люди давно ездят на memcache кеш он для чего нужен? что б скрипты быстрее работали, а скорость нужна там, где ее заранее умные люди проектируют и закладыают на тех решениях, которые дают прирост. а костыли типа этого, это заказчику втереть, что "разработчик" крутой.
440Hz почти раскусил на счёт заказчика 0о естественно, раньше не занимался этим никогда =) А чёж тогда советуют то его все делать? Я тут двиг недавно презентовал, основная критика это отсутствие продвинутой системы кеширования, а я стоял как дурак и не знал что ответить... нет, только если буду делать свой, высоконагруженный проект.
если те будут советовать головой об стенку биться - то ж будешь? надо понимать что и зачем кешируешь. нет смысла кешировать SQL и его ответы, если наружу ты выдаешь всего лишь HTML. Я, к примеру, кеширую (правда в memchahe) куски HTML и страницы собираются уже из готовых кусков. Быстро и со вкусом. На 100 тыс. проекте (dezinfo.net) время сборки полной страницы для отдачи 0.03 сек., хотя там есть SQL на 10-15 сек. в твоем случае кеш на файлах SQL запросов - милая шутка новичка и не более того.
хм, ну вот ты мне щас советушь не делать велосипед Там тоже достаточно опытные люди... дело в том что в некоторых местах у меня нельзя кешировать куски html, а хочецо... (например хочу кешировать комментарии, но там есть такое поле как быстрое администрирование, естественно не для всех пользователей, как быть?)
я храню кеш с разделением по пользхователям и страницам, а вообще, какой ключ захочешь такой и делай для хранения. это твое полное право, а кеш должен просто данные тебе отдать. например name.userid.page и т.д.
А кто советует делать кеш запросов? Ну сам подумай, зачем тебе данные запроса в необработанном и неготовом для вывода виде? Там, где нельзя или логика кеширования слишком сложна - не кешируй. А там где можно - кешируй. Потому и говорю, что можно кешировать куски, а можно страницу целиком: зависит от ситуации.
Плюс есть кеширование на стороне пользователя: управление этим кешем тоже может дать результаты. В CMS'ках вообще зачастую тупо делается "эта страница не будет обновляться еще 5 минут". Такой кеш местами оправдан. Соответственно, и страница берется из кеша, и клиенту отдается заголовок, что не обращайся за этой страницей еще 5 минут: бери из своего кеша. Там, где нужна точность зависимости информации от времени, можно управлять кешем пользователя на основе Last-Modified и E-tag.
ну да, забыл сказать что мне нужно на файлах, мэмкешед нельзя по закрытым для разглашения пичинам =) а, не скажу :twisted: не, не буду говорить вдруг они щас это читают... ну скажем это опытные топ фрилансеры, директор айти компании, преподы в престижных ввузах, вроде кто-то даже на конференции хай-лоад выступает... я их не знаю пока...
это те, кто 99% ниче не понимает в кешировании, а при слове "кеширование" делают умное лицо и кивают головой, мол "одобрям"! =) повторюсь, если те в ЦМС или где еще нужен КЕШ для втирания заказчикам или кому-то там еще. так НАМ и скажи. Мы поймем, а вот ВТИРАТЬ НАМ мозги не надо. Не прокатит.
скажем мне нужно что-то ответить когда мне начнум втирать почему у меня его нет, да так ответить, чтобы не оспорить а ЛИЧНО для себя мне нужно чтобы быстро работало, вот как dezinfo например но желательно всё равно без мэмкешеда... понимают не понимают, а они рулят всей этой отраслью...
я бы говорил всем, что моя систем нстолько быстрая что кеш ей ненужен и пусть ОНИ доказывают что он мне нужен. написать систему которая работет 100% быстро во всех применениях НЕВОЗМОЖНО. и вообще есть золотое правило: оптимизировать нужно тогда, когда тормозит. до этого все заявления об оптимизации сливаются в ноль. посему законный вопрос - где у тебя тормозит? чай не в голове?
дак тормозит понятие растяжимое, один запрос у меня 0.5 сек условно, а другой 1, а я хочу уложится на весь вывод в 1 секунду, вот и тормозит... а вообще, я когда что-то делаю стараюсь думать наперёд, так что надо думать Где БУДЕТ тормозить...а в запросах тормозить будет 100%
ессесно, но кеш-то тут причем? =) говорят же тебе. кешировать надо для начала HTML, а SQL не торогай... вот этим и займись.
html - кеширует, но только статику, надо динамику. ну ТиПа должно быстрее работать если запрос сложный...?
думать ингода тоже ТиПа надо... лана. тебе про кеш вродже объяснили. хочешь SQL кешировать - кешируй... удиви топ-менеджеров новым нюансом. гыгыгы
440Hz У меня есть идея получше, я буду всем говорить типа "Лугов сказал" ггг SQL кеш всётаки сделаю на самом тяжёлом запросе, поставлю обновление кеша не минуту, посмотрим что получится...