我们常常提到用缓存文件来缓存数据库的查询结果,来优化站点的性能,那么这样做的好处到底有多大呢?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的值,它会保证部丢失这些值的类型和结构。

实战演示      

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


[php]  
   view plain 
   copy 
   print 
   ? 
    
    
   
 
   
 
 
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 
   ? 
    
    
   
 
   
 
 
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代码如下: 
 

 
 
   [php]  
   view plain 
   copy 
   print 
   ? 
    
    
   
 
   
 
 
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来强制的删除文件以清空数据缓存