0

我有一个 PHP 应用程序,它在 PostgreSQL 和 MySQL 中使用 PDO 和准备好的语句,我想知道在每次执行之前准备完全相同的语句时是否会影响性能。

在伪代码中,示例如下:

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 中都找不到对它的引用。

4

3 回答 3

1

是的,它在某种程度上违背了使用准备好的语句的目的。准备允许数据库预先解析查询并为执行做好准备。当您执行该语句时,数据库会简单地输入您提供的值并执行最后几个步骤。

当您在这样的循环中进行准备时,所有准备工作都会被丢弃并每次重新完成。你应该拥有的是:

$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));
}

一次准备,多次执行。

于 2013-09-23T15:52:08.623 回答
0

是的,性能受到影响。准备步骤必须解析 SQL 字符串并对其进行分析,以决定它需要访问哪些表以及如何访问(使用哪些索引等)。因此,如果您在循环开始之前准备()一次,然后只在循环内执行(),这可以节省成本。

这是更一般的编程原则的一个示例: 如果代码的结果对于循环的每次迭代都相同,则不应将代码放入循环中。

PS:你不应该使用PDO::prepare(),你应该创建一个 PDO 对象并调用$pdo->prepare().

PPS:您还应该检查 prepare() 和 execute() 的返回值。它们在错误时返回false。或者配置 PDO 以在错误时抛出异常。

于 2013-09-23T15:53:25.477 回答
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));
}
于 2013-09-23T15:53:36.410 回答