自己动手,写一个简单PHP框架 (番外2)

ADODB Recordset Cache 探秘

ADODB支持一种叫 记录集缓存(Recordset Cache) 的技术,可以将查询结果保存到磁盘,再次查询时可以直接读取磁盘的缓存,免去了查询数据库的时间,提高执行效率。
但在使用时,发现官网的手册也有些许错误,而且网上似乎关于这方面的文章比较少,
对于Recordset Cache也仅仅是提到而已,没有更进一步探讨,所以写了这篇文章,也是为自己的框架打一个基础。

如何使用ADODB的记录集缓存

在调用adodb.inc.php之前,定义一个全局变量 $ADODB_CACHE_DIR 来指定记录集缓存的存放位置
$ADODB_CACHE_DIR = ‘/tmp’;
include ‘adodb.inc.php’;
$conn = &ADONewConnection(“Mysql”);
$conn->Connect(‘localhost’, ‘root’, ”, ‘test’);

在查询时使用缓存查询函数,第一个参数是缓存的有效时间
$conn->CacheGetAll(3600, ‘select * from mytable’);

这样,结果记录集就被保存到了 /tmp中,下次有相同的查询就能直接从缓存中读取了。

记录集缓存真的可以提高查询效率吗?

在一张结构简单的表中逐渐增加数据,来观察缓存的执行效率

记录数 缓存大小 普通查询 第一次缓存查询 后续缓存查询 查询速度倍数
5000 278K 0.03 0.05 0.006 5.00
10000 555K 0.055 0.073 0.012 4.58
30000 1697K 0.15 0.2 0.052 2.88
50000 2838K 0.247 0.408 0.12 2.06
100000 5708K 0.48 0.708 0.4 1.20
150000 8627K 0.75 1.14 0.92 0.82

最终使用缓存还没有普通查询效率高!
那到底是什么导致缓存的查询效率反而低了呢?那就要从缓存的原理着手了。

缓存如何生成和匹配

每次执行SQL时,ADODB都会根据一个规则生成缓存散列值,用这个散列值作为文件名去匹配已经存在缓存。
当散列值无法匹配所有的缓存文件时,ADODB就会将本次的查找结果序列化,并以这个散列值进行保存在磁盘中;
当散列值可以匹配某个缓存文件时,就从这个缓存文件中读取数据,而不是去数据库中查找。

1. 缓存文件名构成
缓存文件名 = adodb_散列值.cache
散列值的计算方法是:md5 ( $sql . $databaseType . $database . $user . $mode );
$sql:查询的SQL语句
$databaseType:mysql、odbc……等等
$database:数据库名
$user:数据库用户名
$mode:SetFetchMode的值
所以只有当这些值完全一致时,缓存才能够被匹配

2. 缓存内容
缓存的内容就是经过序列化之后的查找结果,通过unserialize函数就能将缓存内容还原

是什么关系到缓存的执行效率?

现在我们知道了,记录集缓存实际是是从磁盘中读取的文件,再经过unserialize函数进行还原,
所以当缓存内容过大时,unserialize函数的执行时间就会变长,最终unserialize的效率将比数据库查询更低。

Tagged , , , .Bookmark the permalink.

One Response to 自己动手,写一个简单PHP框架 (番外2)

  1. Pingback: Memory Cache小议 - CentOS6 安装Memcached | LaoNi's Blog

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>