针对上次XXX项目连接数据库有timeout现象发生,我做了一次Mysql_connect和mysql_pconnect函数性能比较,仅代表个人观点,难免有不正确之处,欢迎大家讨论。
一、简单介绍
PHP连接mysql数据库,我们通用两种方式,mysql_connect()和mysql_pconnect(),前者的作用是每次连接都建立一个新连接,后者则是持续的连接。mysql_connect()会在每次调用当前php页面时建立一个或是多个新的连接,然后在请求结束后关闭这些连接。这种方式比较适合使用在不太繁重的页面中,不需要调整,直接在内部使用。mysql_pconnect()也会在页面被调用的时候新建一个连接,但是在请求结束后不会关闭连接,反而在把连接保存在连接池中,这样一个并发的请求还能继续使用这个连接。这种连接方式是提供给那些使用非常频繁的页面,不然资源会被频繁的开与关消耗掉,这样就对性能有严重的影响。
为了测试这2个函数的性能,我做个一个小实验。以下是我写的PHP测试函数(请忽略代码的规范性):
1、 mysql_pconnect测试函数代码:
<?php
function Test_Pconnect(){
$dbHost="xxx.xxx.xxx.xx";
$dbUser="xxxx";
$dbPwd="xxx";
$i=0;
while ($i<100)
{
$link = mysql_pconnect($dbHost, $dbUser, $dbPwd) or die('Could not connect: ' .mysql_error());
mysql_close($link);
$i++;
}
}
xhprof_enable();
Test_Pconnect();
$data=xhprof_disable();
include_once"/var/www/ddcollection/xhprof_lib/utils/xhprof_lib.php";
include_once"/var/www/ddcollection/xhprof_lib/utils/xhprof_runs.php";
$objXhprofRun=newXHProfRuns_Default();
$run_id=$objXhprofRun->save_run($data,"pconnect");
var_dump($run_id);
2、 mysql_connect测试函数代码:
<?php
functionTest_connect(){
$dbHost="xxx.xxx.xxx.xxx";
$dbUser="xxxxxr";
$dbPwd="xxxxx";
$i=0;
while($i<100)
{
$link = mysql_connect($dbHost, $dbUser, $dbPwd) or die('Could not connect: ' .mysql_error());
mysql_close($link);
$i++;
}
}
xhprof_enable();
Test_connect();
$data=xhprof_disable();
include_once"/var/www/ddcollection/xhprof_lib/utils/xhprof_lib.php";
include_once"/var/www/ddcollection/xhprof_lib/utils/xhprof_runs.php";
$objXhprofRun=newXHProfRuns_Default();
$run_id=$objXhprofRun->save_run($data,"connect");
var_dump($run_id);
二、结果对比
mysql_pconnect测试结果:
Calls% | IWall% | EWall% | ||||
1 | 0.5% | 83,428 | 100.0% | 20 | 0.0% | |
1 | 0.5% | 83,408 | 100.0% | 5,349 | 6.4% | |
100 | 49.3% | 77,963 | 93.4% | 77,963 | 93.4% | |
100 | 49.3% | 96 | 0.1% | 96 | 0.1% | |
1 | 0.5% | 0 | 0.0% | 0 | 0.0% |
Mysql_connect测试结果:
Calls% | IWall% | EWall% | ||||
1 | 0.5% | 67,785 | 100.0% | 19 | 0.0% | |
1 | 0.5% | 67,766 | 100.0% | 914 | 1.3% | |
100 | 49.3% | 64,899 | 95.7% | 64,899 | 95.7% | |
100 | 49.3% | 1,953 | 2.9% | 1,953 | 2.9% | |
1 | 0.5% | 0 | 0.0% | 0 | 0.0% |
通过以上表格对比发现,mysql_pconnect函数比mysql_connect函数效率要高很多。
注意,如果永久连接的子过程数目超过了您设定的数据库连接数限制,系统将会产生一些缺陷。如果您的数据库的同时连接数限制为 16,而在繁忙会话的情况下,有 17 个线程试图连接,那么有一个线程将无法连接。如果这个时候,在您的脚本中出现了使得连接无法关闭的错误(例如无限循环),则该数据库的 16 个连接将迅速的受到影响。请查阅您使用的数据库的文档,以获取关于如何处理已放弃的及闲置的连接的方法
连接MySQL数据库可以使用mysql_pconnect(永久连接)函数,使用数据库永久连接可以提高效率, 但是实际应用中数据库永久连接往往会导致出现一些问题,通常的表现就是在大访问量的网站上时常发生断断续续的无法连接数据库的情况,出现类似"Too many connections in ..."的错误提示信息,重新启动服务器又正常了,但过不了一会儿又出现同样的故障。对于这些问题的成因,恐怕就不是每个人都能说清楚的了,虽然PHP文档里有一些相关资料,但是解释的并不浅显易懂,这里我厚着脸皮试图做一个以上的简单的结论, 所述观点不见得全都正确,欢迎大家发表自己的意见。