问题描述
|
我正在更新/重做一些数据库代码,我在想,使用准备好的语句应该真正给我带来什么。
请看以下示例代码:
$values = \'\';
for ($i = 0; $i < $count; $i++) {
$name = mysql_real_escape_string ($list[$i][1]);
$voc = mysql_real_escape_string ($list[$i][3]);
$lev = $list[$it][2];
$lev = is_numeric ($lev)? $lev : 0;
$values .= ($values == \'\')? \"(\'$name\',\'$voc\',$lev)\" : \",(\'$name\',$lev)\";
}
if ($values != \'\') {
$core->query (\"INSERT INTO onlineCList (name,voc,lev) VALUES $values;\");
}
现在,除了在可读性(理智性)上获得明显的收益以及“ 1”不再是一个问题的事实之外,当我将其重新编码为使用准备好的语句时,我是否应该期待性能的任何变化?我正在远程连接到MySQL服务器,我担心发送多个小数据包会比发送一个大数据包慢得多。如果是这种情况,MySQLi / mysqlnd可以缓存这些数据包吗?
另一个例子:
$names = \'\';
while ($row = mysql_fetch_array ($result,MYSQL_ASSOC)) {
$name = mysql_real_escape_string($row[\'name\']);
$names .= ($names == \'\') ? \"\'$name\'\" : \",\'$name\'\";
}
if ($names != \'\') {
$core->query (\"UPDATE onlineActivity SET online = NULL WHERE name IN ($names) AND online = 1;\");
}
如上所述,将其重新编码为使用准备好的语句后,是否应该料想不到?如果它必须运行一个带有大IN子句的查询,或者运行带有相等性检查(.. WHERE name = $name AND ..
)的多个准备好的查询,对MySQL服务器有什么区别?
假定所有内容都已正确索引。
解决方法
通常,如果只使用一条准备好的语句代替普通查询,则它会稍微慢一些,因为查询是分两个步骤而不是一个步骤来准备和执行的。仅当您准备语句然后多次执行时,预处理语句才会变得更快。
但是,在这种情况下,您使用的是
mysql_real_escape_string
,它可以往返数据库。更糟糕的是,您正在循环内执行此操作,因此,每个查询多次执行该操作。因此,在这种情况下,用一个准备好的语句替换所有这些往返是双赢的。
关于您的最后一个问题,没有理由您不能像使用普通查询解析器那样对准备好的语句使用相同的查询(即,没有理由使用IN执行一个版本,而使用一堆执行另一个版本。或)。准备好的语句可以具有IN (?,?,?)
,然后只需绑定该数量的参数即可。
我的建议是始终使用准备好的语句。如果它们增加了少量的性能开销,则仍然值得在安全性(无SQL注入)和可读性方面获得好处。可以肯定的是,只要您发现自己求助于mysql_real_escape_string
,就应该改用准备好的语句。 (对于不需要转义变量输入的简单一次性查询,严格来说,它们不是必需的。)
,
预备语句更安全。
预备语句具有更好的性能。
准备好的语句更方便编写。
你会读所有这些!!
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
也尝试一下
预备帐单与存储过程