我是否需要坚持准备好的陈述?

时间:2014-05-29 16:06:47

标签: php pdo mysqli prepared-statement

我有以下代码:

public function getDefinitions($wordID) {
    $query = $this->dbc->prepare('SELECT * FROM definitions WHERE wordID = ?');

    $query->bind_param('i', $wordID);
    $query->execute();

    // ...

    $query->close();

    return $result;
}

这似乎会为每次调用重新创建prepared statement。这似乎没有利用准备好的陈述的全部好处。特别是在这些准备陈述是stored server side的情况下。这是真的吗?

如果是这样,我应该将prepare语句(在本例中作为属性)存储在调用之间。有没有办法在请求之间保留准备好的语句?我认为这基本上是一个存储过程?

目前我正在使用MySQLi。如果我使用其他驱动程序(例如PDO),请注意任何API差异。

2 个答案:

答案 0 :(得分:7)

  

我应该将prepare语句(在本例中作为属性)存储在调用之间保存它。

我不会说你"应该"。如果你预见到很多后续的调用(你不能组成一次调用),你可能会这样做。无论哪种方式,你几乎都不会注意到现实生活中的差异。

  

有没有办法在请求之间保留准备好的语句?

在PHP中 - 没有。准备好的语句是基于连接的,连接与请求一起关闭,持久连接也不会帮助您,因为mysqli is using designated mechanism在重用之前清除连接状态。

  

如果我使用其他驱动程序(例如PDO),请注意任何API差异。

PDO优于mysqli,因为它可以模拟准备好的语句,甚至可以消除两个数据库调用的这种可忽略的开销,这使得它更适合现实生活中使用(除了其他关键优势) 。

简而言之,"准备一次多次执行"本机预处理语句的功能只能对大量查询产生明显影响,从数千个查询开始。

答案 1 :(得分:1)

如果您打算再次使用它,则应该保留查询。

当你使用mysqli时,准备好的语句应该始终是真正准备好的语句。 (与PDO相反,PDO根据使用的驱动程序模拟查询,可能不会发送额外的数据库调用)。然后,将替换占位符的数据发送到不同的数据包中。 因此,如果只发布一次,那么本地准备的声明需要两次访问数据库。 发送这个额外的动作需要时间。如果您知道自己只想发出一次查询,那么在某些情况下使用传统查询可能会有积极意义。 (但是,如果您绝对确定标准查询与准备好的语句相比具有潜在的负面安全隐患,那么这只是可取的。使用预准备语句增加的级别安全性远远超过了这样的好处在大多数情况下,可能会有更改。)

但是,如果您想重新运行查询,那么准备它是正确的方法。 MySQL应该缓存转换后的语句,因此php-site是优化和重用的唯一方法。

您可以做的是通过使用静态变量或属性保留方法中的语句来阻止对prepare方法的附加调用以及它可能在低级数据库连接器中触发的操作。然而,对大多数实际应用程序的影响是有争议的。