PHP实现数据库结果查询缓存

我们常常提到用缓存文件来缓存数据库的查询结果,来优化站点的性能,那么这样做的好处到底有多大呢?PHP又怎么样去实现结果缓存呢?结合自己的测试和大牛们的博客,在这里来谈谈PHP实现数据库结果查询缓存

一、这样做的好处到底有多大

<?php
#记录开时间 ms
$time = explode (' ', microtime ());  
$start = $time [1].($time[0]*1000); 

#链接数据库
$conn = mysqli_connect("localhost","root","","test");  
#设置编码
$setting = 'set names utf8';  
mysqli_query($conn,$setting);  
#查询
$sql = 'SELECT * FROM user';  
$result = mysqli_query($conn,$sql);  
#查询结果转化为一个数组  
$rows = mysqli_num_rows($result);  
$data = array();  
for($i = 0;$i <$rows;$i ++){  
    $data[] = mysqli_fetch_assoc($result);  
}

#记录结束时间 ms
$time = explode ( " ", microtime () );  
$end = $time [1] . ($time [0] * 1000);
#输出从数据库读取数据的时间  
echo $end-$start.'</br>'; 

#结果写到缓存文件  
$data = serialize($data);  
file_put_contents('cache.txt', $data);

#记录开时间 ms
$time = explode (' ', microtime ());  
$start = $time [1].($time[0]*1000); 

#从文件缓存读数据
$data=file_get_contents('cache.txt');
$data= unserialize($data);

#记录结束时间 ms
$time = explode ( " ", microtime () );  
$end = $time [1] . ($time [0] * 1000);
#输出从缓存文件读取数据的时间    
echo $end-$start.'<br>'; 


上面的表中大概有5000条数据,在我的机器上运行的结果为,从数据库读取数据的平均时间为“145ms”,从缓存文件中读取数据的平均时间为“70ms”,由此可见,从缓存文件中读取数据的性能比从数据库读取要好上一倍。

二、怎么样用PHP实现数据库结果查询缓存(以下内容来自他人博客)

 有些时候我们希望减少对数据库的查询来提高程序的性能,因为这些数据不是经常变更的,而是会在很长一段时间内都不会变化,因此,我们每连接一次数据库,都会把相应的结果用文件的形式保存起来。比如对于一个商城来说,我们的商品的数量可能会经常变,但是我们的商品类型以及商品的价格这些东西都会在很长的一段时间内不会变更,如果我们需要频繁的查询它们的时候,就可以使用数据库缓存技术。

缓存的原因

     第一点首先看我们普通情况下执行一条SQL查询的开销,我们先连接数据库,然后准备SQL查询,接下来发送查询信息,然后取得返回结果,最后关闭数据库连接,这样的话会占用较多的资源,而我们的PHP程序也因为要等待从数据库中查询而使得响应速度变慢。

       第二点就是在数据库压力较大时,比如高峰时段,这个时候数据库压力大,我们就需要把一些数据存储到硬盘上,用文件的形式去读取,这样的做法是用我们的硬盘空间换取数据库的压力,这一点也要看机器性能。

      第三点就是有些数据不着急去更新,比如上面提到的商品类型表,就不会太急于更新,比如我们的用户的核心信息,一般也不会轻易去修改密码什么的,这些内容可以选择用文件的形式去缓存起来。

缓存的实现原理

      第一点就是我们要确定何时强制更新内容,最常见的有三种方式就是第一个就是用时间去触发,我们通常使用时间戳,第二点就是发现数据库数据被修改,则自动更新缓存,第三个就是人工触发,我们用人工的防水告诉信息系统强制更新缓存内容。

      第二点就是我们可以通过使用serialize()函数来把从数据库中取得的数据进行序列化,保存为本地文件,然后我们通过unserialize来从本地文件中读取信息,所谓序列化就是用特定的方式去存储PHP的值,它会保证部丢失这些值的类型和结构。

实战演示      

     我们首先把从数据库中读取的数据存入本地文件,代码如下:

  1. <?php  
  2. //第一步连接数据库  
  3. $conn = mysqli_connect("localhost","root","","bbs");  
  4. //第二步设置相应的字符编码  
  5. $setting = 'set names utf8';  
  6. mysqli_query($conn,$setting);  
  7. //第三步进行查询  
  8. $sql = 'SELECT * FROM user';  
  9. $result = mysqli_query($conn,$sql);  
  10. //第四步把查询结果转化为一个数组  
  11. $rows = mysqli_num_rows($result);  
  12. $sqldata = array();  
  13. for($i = 0;$i <$rows;$i ++){  
  14.     $sqldata[] = mysqli_fetch_assoc($result);  
  15. }  
  16. //第五步把结果写到缓存文件  
  17. $file = "sqlcache.txt";  
  18. $msg = serialize($sqldata);  
  19. $fp = fopen($file,"w");  
  20. fputs($fp,$msg);  
  21. fclose($fp);  

然后我们可以打开这个sqlcache.txt文件,它的内容如下:

[javascript]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. a:6:{i:0;a:4:{s:2:"id";s:1:"1";s:5:"level";s:1:"0";s:4:"name";s:6:"辛星";s:3:"pwd";s:32:"bd04fcc97578ce33ca5fb331f42bc375";}i:1;a:4:{s:2:"id";s:1:"2";s:5:"level";s:1:"1";s:4:"name";s:6:"小倩";s:3:"pwd";s:32:"61cb72858be523b9926ecc3d7da5d0c6";}i:2;a:4:{s:2:"id";s:1:"3";s:5:"level";s:1:"1";s:4:"name";s:6:"小楠";s:3:"pwd";s:32:"a3d2de7675556553a5f08e4c88d2c228";}i:3;a:4:{s:2:"id";s:1:"4";s:5:"level";s:1:"1";s:4:"name";s:6:"刘强";s:3:"pwd";s:32:"fcdb06a72af0516502e5fdccc9181ee0";}i:4;a:4:{s:2:"id";s:1:"5";s:5:"level";s:1:"1";s:4:"name";s:6:"星哥";s:3:"pwd";s:32:"866a6cafcf74ab3c2612a85626f1c706";}i:5;a:4:{s:2:"id";s:1:"6";s:5:"level";s:1:"1";s:4:"name";s:6:"辛勇";s:3:"pwd";s:32:"e93beb7663f3320eaa0157730d02dd0c";}}  
然后我们可以写一个程序从该文件中读取数据,PHP代码如下:

  1. <?php  
  2. $file = "sqlcache.txt";  
  3. $msg = file_get_contents($file);  
  4. $result = unserialize($msg);  
  5. var_dump($result);  

这样我们的$result就是从本地的txt文件中读取的数据,而不是从数据库中读取的数据了,即我们模拟了缓存的使用。


说明:

1.我们通过filemtime来得到文件的创建时间,可以用time来得到现在的时间,通过比较这个差值来决定是否要更新缓存。

2.我们可以用unlink来强制的删除文件以清空数据缓存




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值