在关于mysql是否支持绑定变量功能,和mysql的绑定变量功能是不是鸡肋的说法和讨论比较多,今天我就做个小实验,测试下php+mysql的绑定变量功能是否能够提高web和mysql的性能,提高的比率有多少。
测试方法,主要采取,在绑定变量前后对PHP脚本的执行时间的测试,和pfiles工具对sql语句执行的资源使用情况统计。
测试环境如下:
RHEL5.4
mysql> select version();
+------------+
| version() |
+------------+
| 5.1.44-log |
+------------+
PHP 5.2.10 with Suhosin-Patch 0.9.7 (cli) (built: Aug 13 2010 09:14:57)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
with Zend Optimizer v3.3.3, Copyright (c) 1998-2007, by Zend Technologies
绑定变量测试,插入10条记录句执行10次,每次数据库所用时间如下(使用profile计算,见mysqli_stmt.php):
0.000102
0.000093
0.000102
0.000102
0.000094
0.00013
0.000102
0.0001
0.000138
0.000095
总共平均时间:0.0001058
使用linux time命令计算绑定变量的php脚本执行时间
real 0m0.039s
user 0m0.024s
sys 0m0.013s
user 0m0.027s
sys 0m0.011s
user 0m0.025s
sys 0m0.012s
user 0m0.026s
sys 0m0.012s
user 0m0.021s
sys 0m0.019s
user 0m0.029s
sys 0m0.010s
user 0m0.020s
sys 0m0.018s
user 0m0.025s
sys 0m0.013s
user 0m0.029s
sys 0m0.009s
user 0m0.026s
sys 0m0.014s
不使用绑定变量测试,插入10条记录句执行10次,每次数据库所用时间如下(使用profile计算,见mysqli_nobind.php):
0.000103
0.000104
0.000114
0.000103
0.000119
0.000113
0.000114
0.000102
0.00012
0.00012
平均执行时间:0.000112
real 0m0.040s
user 0m0.026s
sys 0m0.014s
user 0m0.027s
sys 0m0.011s
user 0m0.028s
sys 0m0.009s
user 0m0.027s
sys 0m0.011s
user 0m0.023s
sys 0m0.015s
结论:(未绑定变量的sql平均执行时间-绑定变量sql的平均执行时间)/未绑定变量的执行时间=0.0553571428571429约为6%。
总体提升了6%左右的性能。
一样的,包括打开表,获得锁资源,执行语句,记录日志,释放资源等。
不过对于绑定变量的可用性还是不容怀疑的,在大型系统上5%的性能提高已经很不错了,加上绑定变量的安全性,可以很好的规范SQL语句的
验证,避免自己单独去写验证语句,推荐使用绑定变量。
[root@zj7 learn_php]# cat mysqli_stmt.php
<?php
$mysqli=new mysqli("localhost", "root", "123321", "test");
$sql1="set @@profiling=1";
$result1=$mysqli->query($sql1);
//准备好一条语句放到服务器中,插入语句
$sql="insert into t(name,sex) values (?,?)";
$stmt=$mysqli->prepare($sql);
//给占位符号每个?号传值(绑定参数) i d s b
$stmt->bind_param("si", $name, $sex);
$name="andy";
$sex=0;
//执行
$stmt->execute();
$name="mandy";
$sex=1;
//执行
$stmt->execute();
$name="michael";
$sex=0;
//执行
$stmt->execute();
$name="happy";
$sex=1;
//执行
$stmt->execute();
$name="php";
$sex=1;
//执行
$stmt->execute();
$name="mysql";
$sex=1;
//执行
$stmt->execute();
$name="linux";
$sex=1;
//执行
$stmt->execute();
$name="oracle";
$sex=1;
//执行
$stmt->execute();
$name="unix";
$sex=1;
//执行
$stmt->execute();
$name="cisco";
$sex=1;
//执行
$stmt->execute();
$stmt->close();
$sql2="show profiles";
$result2=$mysqli->query($sql2);
echo '<table border=1 align="center" width=800>';
while($rows=$result2->fetch_assoc()){
echo '<tr align="center">';
foreach($rows as $value){
echo '<td>' . $value . '</td>';
}
echo '</tr>';
$i=0;
$i=$i+$rows["Duration"];
}
echo '</table>';
echo $i;
?>
[root@zj7 learn_php]# cat mysqli_nobind.php
<?php
$mysqli=new mysqli("localhost", "root", "123321", "test");
$sql1="set @@profiling=1";
$result1=$mysqli->query($sql1);
$nobind=array("insert into t(name,sex) values ('andy',0)",
"insert into t(name,sex) values ('mandy',1)",
"insert into t(name,sex) values ('michael',0)",
"insert into t(name,sex) values ('happy',0)",
"insert into t(name,sex) values ('php',0)",
"insert into t(name,sex) values ('mysql,0)",
"insert into t(name,sex) values ('linux',0)",
"insert into t(name,sex) values ('oracle',0)",
"insert into t(name,sex) values ('cisco',0)",
"insert into t(name,sex) values ('unix',0)");
foreach($nobind as $sql){
echo $sql;
$result=$mysqli->query($sql);
}
$sql2="show profiles";
$result2=$mysqli->query($sql2);
echo '<table border=1 align="center" width=800>';
while($rows=$result2->fetch_assoc()){
echo '<tr align="center">';
foreach($rows as $value){
echo '<td>' . $value . '</td>';
}
echo '</tr>';
$i=0;
$i=$i+$rows["Duration"];
}
echo '</table>';
echo $i;
$mysqli->close();
?>

















