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的效率将比数据库查询更低。
From LaoNi 的博客, post 自己动手,写一个简单PHP框架 (番外2)
Pingback: Memory Cache小议 - CentOS6 安装Memcached | LaoNi's Blog