发布于:
2008年04月25日
本文的目的:
1. 众所周知,连接一个数据库过程对资源开销很大 ,Oracle官方文档针对PHP部分也佐证了这一点。所以第一个目的是为了证明跟一条普通的SQL语句相比,到底开销相差有多大。
2. 本人接触Oracle 没有多久,听说Oracle有一个较大的缓存池,保持最近运行的语句,以提高重复运行相同语句的效率。目的二是为了证明缓存池有多大影响。
测试环境:
1. 本机安装:Apache 2.2.8+PHP5.2.5 +Oracle Client 10.2.01
2. 连接Oracle 独立服务器,服务器版本:Oracle 10g
测试代码:
//PHP连接Oracle函数
function conn_ora(){
$username='test';
$passwd='test';
$protocol='TCP';
$SERVICE_NAME='testdb';
$ORACLE_SERVER_IP_ADDRESS='192.168.0.10';
$Port='1521';
PutEnv("NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8");
if(!$conn = @oci_pconnect($username, $passwd, "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = $protocol)(HOST = $ORACLE_SERVER_IP_ADDRESS)(PORT = $Port)) ) (CONNECT_DATA = (SERVICE_NAME = $SERVICE_NAME) ) )")) echo("Error in Connecting to DataBase");
return $conn;
}
//计时函数:
function microtime_float(){
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
//query 函数
function ora_query($sql){
global $conn_ora;
$result=oci_parse($conn_ora,$sql);
oci_execute($result,OCI_DEFAULT);
return $result;
}
连接数据库测试代码:
$time_start=microtime_float();
$num=1000; // 测试的次数,将进行100次和1000次测试
for($i=0;$i<$num;$i++){
$conn_ora=conn_ora();
oci_close($conn_ora);
}
$time_end=microtime_float();
$time_spend=$time_end-$time_start;
echo "Script run time: $time_spend sec. \n";
SQL语句执行测试代码:
$conn_ora=conn_ora();
$time_start=microtime_float();
$num=1000; // 测试的次数,将进行100次和1000次测试
for($i=0;$i<$num;$i++){
$sql="select * from test_table where rownum<10 ";
$result=ora_query($sql);
}
$time_end=microtime_float();
$time_spend=$time_end-$time_start;
oci_close($conn_ora);
echo "Script run time: $time_spend sec. \n";
执行顺序:
条件一:执行1000次‘SQL语句执行测试代码’;
条件二:执行1000次‘连接数据库测试代码’;
条件三:执行100次‘连接数据库测试代码’;
条件四:执行100次‘SQL语句执行测试代码’;
以上每个条件的脚本执行5次,取时间
结果如下:
条件一:执行1000次‘SQL语句执行测试代码’;
0.9970sec
0.8482sec
0.8777sec
0.8552sec
0.8505sec
条件二:执行1000次‘连接数据库测试代码’;
1.6175sec
1.6457sec
1.6064sec
1.6380sec
1.6083sec
条件三:执行100次‘连接数据库测试代码’;
0.1833sec
0.1532sec
0.1552sec
0.1561sec
0.1818sec
条件四:执行100次‘SQL语句执行测试代码’;
0.0984sec
0.1203sec
0.1004sec
0.1011sec
0.1177sec
通过以上数据得出以下结论:
1.连接数据库比普通SQL语句的系统开销稍大,但没有“很大”:1000次测试在时间上大概在2 倍左右;100次测试仅为1.5倍左右。当然CPU,内存等其他开销,本次测试无法给出
2.从’条件一’的5个时间结果可以看到,第一个时间0.9970比其余时间明显偏大0.1sec以上,看起来缓存机制在其作用。后续测试没有相同情况出现,也正印证了缓存机制的作用。
3.1000测试与100次测试,相同代码花费时间基本呈线性的10倍关系 。可见当中没有明显的其他因素影响。
##########################################
##############以下为改变条件重复测试##############
##########################################
在观众的提点下,修改条件重复测试。
首先,将oci_pconnect()改为oci_connect(),重做以上测试:(测试代码参考上文,不再重复书写)
测试结果:
条件一:执行1000次‘SQL语句执行测试代码’;
0.8038sec
0.8344sec
0.8591sec
0.8523sec
0.8402sec
条件二:执行1000次‘连接数据库测试代码’;
超过页面执行时间,php.ini设定为30sec
条件三:执行100次‘连接数据库测试代码’;
7.1286sec
7.1195sec
6.8513sec
7.0622sec
6.6788sec
条件四:执行100次‘SQL语句执行测试代码’;
0.1170sec
0.1138sec
0.0836sec
0.0839sec
0.0838sec
然后,新曾测试条件:先连接数据库,然后执行一条SQL语句,最后关闭,循坏执行以上步骤,测试代码:
$conn_ora=conn_ora();
$time_start=microtime_float();
$num=1000; // 测试的次数,将进行100次和1000次测试
for($i=0;$i<$num;$i++){
$conn_ora=conn_ora();
$sql="select * from test_table where rownum<10 ";
$result=ora_query($sql);
oci_close($conn_ora);
}
$time_end=microtime_float();
$time_spend=$time_end-$time_start;
oci_close($conn_ora);
echo "Script run time: $time_spend sec. \n";
条件五:上面代码执行100次
条件六:上面代码执行1000次
条件七:将上面代码改用oci_pconnect执行1000次
结果数据:
条件五:
0.4013sec
0.3804sec
0.3789sec
0.3482sec
0.3447sec
条件六:
2.6904sec
2.7077sec
2.7644sec
2.7573sec
2.7476sec
条件七:
2.6194sec
2.5633sec
2.8788sec
2.7847sec
2.5538sec
结论更新:
1. oci_pconnect()改为oci_connect()后,‘条件一’和’条件四’结果几乎没有变化。这是可以预期的,因为这两个条件只执行了一次连接。
2.oci_pconnect()改为oci_connect()后,’条件三’产生了超过40倍的增加,‘条件四’没有数据,按照线性倍增推算,该条件运行会超过70sec。这点跟新增条件结果放在一起,让我非常不解,还请高人指点。
3.新增条件(条件五,六,七)重复“连接数据库,运行SQL,断开数据库”步骤,原‘条件一’和’条件四’相比,时间增加约为3.3倍,
4.新增条件(条件五,六,七)下,采用“oci_pconnect()”和“oci_connect()”几乎没有变化。但是这个与’条件三’产生了巨大的矛盾。
针对oci_pconnect()和oci_connect()疑问:
为何重复进行”连接和断开”过程中,oci_pconnect()和oci_connect()有如此大的差异,而中间有查询过程的情况下,差异可以忽略?
##########################################
####################END###################
##########################################
本文为寻找人生的起点(http://blog.cn-ic.org)原创,如需转载,请注明出处,并保留原文链接 http://blog.cn-ic.org/?p=84。