【发布时间】:2012-08-27 14:01:57
【问题描述】:
我曾经在查询中有相当多的多个联接。
为了能够(至少)使用内置的 MySql Cache 功能,我编写了以下函数, 它只是将原始查询编码为 base64,检查它是否存在且未过期。
这极大地提高了性能,而且我的优势是可以在源代码中控制缓存时逐个查询。
但在繁忙时间,由于删除或选择时间过长,表格变得不可用。有什么建议可以让这个运行更快并避免前面提到的问题吗?
表:
CREATE TABLE `cachesql` (
`id` int(9) NOT NULL AUTO_INCREMENT,
`expire` int(15) NOT NULL,
`sql` text NOT NULL,
`data` mediumtext NOT NULL,
PRIMARY KEY (`id`,`sql`(360)),
KEY `sdata` (`sql`(767)) USING HASH
) ENGINE=InnoDB
功能:
function fetchRows_cache($sql,$cachetime,$dba){
// internal function (called by fetchRows)
global $Site;
$expire = 0;
$this->connect($dba);
// check if query is cached
$this->q = mysql_query("SELECT `expire`,`data` from cachesql where `sql`='".base64_encode($sql)."' limit 1;", $this->con) OR $this->error(1, "query$".$sql."$".mysql_error());
$this->r = mysql_fetch_assoc($this->q);
$expire = $this->r['expire'];
$data = $this->r['data'];
if (($expire < time())||($cachetime =="0")) { // record expied or not there -> execute query and store
$this->query("DELETE FROM `cachesql` WHERE `sql`='".base64_encode($sql)."'",$dba); // delete old cached entries
$this->q = mysql_query($sql, $this->con) OR $this->error(1, "query$".$sql."$".mysql_error());
$this->r=array();
$this->rc=0;
while($row = mysql_fetch_assoc($this->q)){
$arr_row=array();
$c=0;
while ($c < mysql_num_fields($this->q)) {
$col = mysql_fetch_field($this->q, $c);
$arr_row[$col -> name] = $row[$col -> name];
$c++;
}
$this->r[$this->rc] = $arr_row;
$this->rc++;
}
$out = $this->r;
// write results into cache table
if ($cachetime != "0") {
// not store cache values for now (too many locks)
$this->query("INSERT INTO `cachesql` (`sql`,`data`,`expire`) VALUES ('".base64_encode($sql)."','".mysql_real_escape_string(serialize($out))."','".(time()+$cachetime)."')",$dba);
}
return $out;
}
else { // use Cached data
return unserialize($data);
}
}
【问题讨论】:
-
因为 sql 是一个文本字段,它不能真正用作主键。内存表也是如此,SQL 的 VarChar 字段也不完全可能,因为查询可能比 256 字节长得多。
-
我的想法是将校验和存储在 varchar 字段中而不是完整的查询中,但我不知道这是否是一个聪明的主意……有什么想法吗?
-
校验和是指MD5还是其他类似的哈希码? MD5 存在加密问题,但对您的目的应该没问题。
-
改用memcached怎么样?
-
@nullx8:自 5.0.3 以来,varchar 最长可达 64k。但是,这么大的 varchar 上的索引会很慢。
标签: php mysql query-cache