我有一个共享主机,但功能有限。Memcache和mod_cache对我不可用。我想实现我自己的PHP缓存方法来缓存负载密集型SQL查询的结果。在SQL中使用汇总表是不可取的,因为查询需要多个参数,这些参数可以采用数千个不同的值(这是一个统计系统)。
我的想法是这样的:
function execQuery($parameter)
{
$query = "SELECT ....... " . $parameter; //query code has been generated
$rand = mt_rand(0,10);
//no need to check/save expiry dates,generate cache randomly for speed
if($rand == 0)
{
//execute query normally and generate new cache
$result = mysql_query($query);
$md5 = md5($query); // the name of the cache file equals the md5 of the query
$cache_file = fopen("/cache/" . $md5 ."php", "w");
fwrite($cache_file, $result); // the result is written as php code generating a ready for use result array, code has to be modified I think
//return the result
}
else
{
//cache will be used
$md5 = md5($query);
if(file_exists("/cache/" . $md5 ."php"))
{
include("/cache/" . $md5 ."php");
return $result;
}
else
{
//no cache exists, run query normally and generate cache
}
}
}您对此有何看法?可能的陷阱是什么?使用mt_rand、md5的含义是什么?您认为它们的性能会超过负载密集型查询吗?多次系统文件写入是否值得(每10次命中仅写入一次,甚至可以增加)?
发布于 2014-07-13 16:08:23
文件缓存是很多系统使用的东西(可能是因为很多主机没有提供其他缓存机制),所以一般来说,这是一种很好的方法。然而,使用rand而不是修改日期将不能很好地扩展。如果你有1000个访问量呢?这意味着允许100个查询命中数据库。因此,您的方法应该基于到期日期。此外,如果查询开销很大,则每当您触发重新生成时,都会对文件执行touch操作(以便更新修改日期),这样其他命中就不会触发重新生成。
此外,您应该以这样一种方式构建代码:检查文件是否存在,如果它在同一步骤中没有过时,并且只有一个代码用于生成:
function execQuery($parameter)
{
$query = "SELECT ....... " . $parameter; //query code has been generated
$md5 = md5($query); // the name of the cache file equals the md5 of the query
$cache_file = "/cache/" . $md5 ."php");
$expire = 600; // seconds
if(!file_exists($cache_file) || mtime($cache_file) < time() - $expire)
{
touch($cache_file);
//execute query normally and generate new cache
$result = mysql_query($query);
$fp = fopen($cache_file, "w");
fwrite($fp, serialize($result)); // the result is written as php code generating a ready for use result array, code has to be modified I think
fclose($fp);
}
return unserialize(file_get_contents($cache_file));
}您不应该保存由mysql_query返回的resource变量,而应该实际获取数据(否则您将无法使用它)。
一般来说,缓存的工作原理是单次写入,多次读取,所以它不会那么慢。当然,它比在内存中加载要慢,但读取大量的文件无论如何都会被操作系统缓存。
https://stackoverflow.com/questions/24719779
复制相似问题