我有一个PHP应用程序,它使用PDO和PostgreSQL和MySQL中的预处理语句,我想知道在执行它之前每次准备完全相同的语句是否会有性能损失。
在伪代码中,一个例子是:
for ($x=0; $x<100; $x++) {
$obj = PDO::prepare("SELECT x,y,z FROM table1 WHERE x=:param1 AND y=:param2");
$obj->execute(array('param1'=>$param1, 'param2'=>$param2));
}
与准备一次并多次执行相反:
$obj = PDO::prepare("SELECT x,y,z FROM table1 WHERE x=:param1 AND y=:param2");
for ($x=0; $x<100; $x++) {
$obj->execute(array('param1'=>$param1, 'param2'=>$param2));
}
我多次搜索过这个问题,但似乎无法在PHP,PostgreSQL和MySQL中找到它的引用。
答案 0 :(得分:1)
是的,它在某种程度上违背了使用准备好的陈述的目的。准备允许DB预先解析查询并准备好执行。当您执行该语句时,数据库只会滑入您提供的值并执行最后几个步骤。
当你在这样的循环内准备时,所有的准备工作都会被抛出并每次都重新完成。你应该拥有的是:
$obj = PDO::prepare("SELECT x,y,z FROM table1 WHERE x=:param1 AND y=:param2");
for ($x=0; $x<100; $x++) {
$obj->execute(array('param1'=>$param1, 'param2'=>$param2));
}
准备一次,执行多次。
答案 1 :(得分:0)
是的,性能受到了打击。准备步骤必须解析SQL字符串并对其进行分析以确定它需要访问哪些表以及它将如何执行(要使用哪些索引等)。因此,如果您在循环开始之前准备一次(),然后在循环内执行(),这可以节省成本。
这是一个更通用的编程原则的示例:如果代码的结果对于循环的每次迭代都相同,则不应将代码放在循环中。
PS:你不应该使用PDO::prepare()
,你应该创建一个PDO对象并调用$pdo->prepare()
。
PPS:您还应该检查prepare()和execute()的返回值。他们会在错误时返回 false 。或者配置PDO以在出错时抛出异常。
答案 2 :(得分:0)
为什么不这样做?它当然会执行求解器。但由于在准备过程中没有与数据库连接或进行繁重的计算(因为查询很短),速度变化将是微不足道的,但这是一种糟糕的风格。
$obj = PDO::prepare("SELECT x,y,z FROM table1 WHERE x=:param1 AND y=:param2");
for ($x=0; $x<100; $x++) {
$obj->execute(array('param1'=>$param1, 'param2'=>$param2));
}