我正在更新/重新编写一些数据库代码,我想知道我应该真正期望使用预准备语句。
以此示例代码:
$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', '$voc', $lev)";
}
if ($values != '') {
$core->query ("INSERT INTO onlineCList (name, voc, lev) VALUES $values;");
}
现在,除了可读性(理智)明显增加以及max_packet_size
不再成为问题这一事实之外,当我重新编写使用预准备语句时,我是否应该期待性能的任何变化?我正在远程连接到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;");
}
如上所述,我是否应该在重新编码后使用准备好的语句?它是否对MySQL服务器有任何影响,如果它必须运行一个带有大IN子句的查询,或者多个准备好的查询带有相等性检查(.. WHERE name = $name AND ..
)?
假设所有内容都已正确编入索引。
答案 0 :(得分:10)
通常情况下,如果您只使用预准备语句代替普通查询,那么它会稍微慢一些,因为查询是以两步而不是一步的方式准备和执行的。只有当您准备语句然后多次执行时,准备好的语句才会变得更快。
但是,在这种情况下,您使用的是mysql_real_escape_string
,它会对数据库进行往返。更糟糕的是,你是在循环中进行的,所以,每次查询多次执行。因此,在这种情况下,用一个准备好的声明替换所有这些往返是一种双赢。
关于你的上一个问题,你没有理由不像正常的查询解析器一样使用预准备语句的相同查询(即没有理由用IN执行一个版本而另一个用一堆OR执行)。 prepared statement可以有IN (?, ?, ?)
,然后您只需绑定该数量的参数。
我的建议是始终使用准备好的陈述。如果它们增加了边际性能开销,那么它们仍然值得为安全性(无SQL注入)和可读性带来好处。当然,只要您发现自己诉诸mysql_real_escape_string
,就应该使用准备好的声明。 (对于简单的一次性查询,不需要转义变量输入,它们不是绝对必要的。)
答案 1 :(得分:0)
你会读完所有这些!!
http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
试试这个