thinkphp mysql cache_ThinkPHP关于数据库Cache的一些注意事项

d4926ed88592a9cc996fb9bc4588b140.png

在做一个比较简单的数据接口,虽然数据量并不大就几万条,但是为了增加响应速度以及减少资源占用,使用了其中的数据库缓存技术。

笔者大概对比了一下日志,直接访问数据库和使用缓存的耗时相差达到了3-5倍。

不过这个数据跟很多方面有关系,首先是数据库缓存方式,我选择了File,因此本地磁盘以及服务器的I/O性能对耗时影响应该是最大的了,所以数据并不官方,只是想说尽量使用缓存能给你的项目带来很大的帮助。

ThinkPHP对缓存方式的支持比较多,有file、memcache、wincache、sqlite、redis和xcache,所以我尝试了一下使用sqlite,结果却以失败告终。

15bd25c216c9557e8ce8f6f5afbdcec8.png

尝试过修改官方 think\Cache\Sqlite 驱动,然后配置了PHP对sqlite的支持,但还是报了各种错误,所以还是暂时放弃了,毕竟主要的目的还是正在做的项目接口嘛。

首先是一个获取随机数据的需求,ORDER BY RAND()就不讲了,效率超差+官方不推荐+有更好的解决方案,不用说直接忽略了。

最终使用SQL确定下来就是通过聚合函数 MAX() MIN() 以及 RAND() 来实现。

但是结合到ThinkPHP感觉还是有点复杂,而且每次查询仍然得访问数据库,加上SQL略多,所以效率上还是值得再优化的。

想了一下解决方案,最终结合ThinkPHP的缓存完成了需求,数据缓存后查询数据甚至不用连接数据库。

其实过程还是比较蛋疼了,因为总共有4个接口,每个接口得单独的写代码,因为新加的这个需求,代码简单重构了一下,不论limit多少数据都会缓存全部符合条件的数据,然后根据返回的数据二次加工返回指定数量。

惯性思维的锅,如果要获取1条数据,但却取出100条数据,任何人哪怕不是写代码的都知道这个肯定会花费很多时间。

但有了缓存,就得换个思维了,因为接口还支持设置指定数量的数据,所以倒不如将接口统一,先将所有符合条件的数据缓存,然后根据数量进行返回。

于是将多个接口最终统一到了一个接口上,效率也得到了明显的提高。代码如下:1

2

3

4

5

6

7

8private function data($date, $start = 0, $limit = 10, $field = 'id, y AS type')

{

$data = Users::where('i', $date)

->field($field)

->cache('tag_date' . $date, 3600)

->select();

return array_slice($data, $start, $limit);

}

同时,需要注意在链式查询当中,cache() 方法只能用一次,官方文档中并没有说明这个。

错误的写法是这样的:1

2

3

4

5

6

7

8

9public function test()

{

return Users::where()

->field('id, un, pw')

->cache('test')

->limit(10)

->cache('test_limit_10')

->select();

}

在接口还没改动的时候,我是打算查到所有数据后将所有数据缓存,然后查询前10条的时候缓存一次,这样别的接口可以复用这个查询所有的缓存。

但很显然这是个失败的尝试,反而导致了接口获取的数据不正确,所以要注意一下:cache方法在一链条式查询当中只会产生一次,以最后一次为准。

另外就是缓存标识在不同的查询间一定要用不同的标识区分,否则新缓存覆盖同名标识的旧缓存,会导致数据查询为别的同名接口查出的数据。

注意我使用的版本是ThinkPHP5.0.4版本,其他版本可能有差异,详情请参考官方历史版本更新日志中关于数据库缓存的修改说明。

随便说说,可能有点啰嗦……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值