3

我正在将旧(杂乱)代码从 mysql_query() 更新为 PDO。

我知道使用准备好的语句对安全性和性能都有好处,但是要发挥性能方面的作用,必须先进行准备,然后再执行多次。这意味着对我的代码进行重大重写,这可能不值得提高性能,但后来我想知道我是否可以用另一种方式来做。

我提出的解决方案是将 PDO 类包装如下:

 class PDOCached extends PDO {

      private $PreparedStatementCache;

      public function prepare($query) {

          if (!isset($this->PreparedStatementCache[$query])) {              
                $this->PreparedStatementCache[$query]=parent::prepare($query);
          }

          return $this->PreparedStatementCache[$query];
      }
 }

它有效(即我得到相同的结果),但我不清楚它是否允许我利用性能提升。任何反馈/意见表示赞赏。

注意:我知道这没有考虑 $driver_options,但是对于这个练习来说这并不重要。


更新:

我已经修改了类以使缓存成为可选:

 class PDOCached extends PDO {

      private $PreparedStatementCache;

      // WARNING: Does not take into account $driver_options
      public function prepare($query, $cached=false) {

          if (!$cached) return parent::prepare($query);

          if (!isset($this->PreparedStatementCache[$query])) {  
                // WARNING: Assumes try/catch error handling            
                $this->PreparedStatementCache[$query]=parent::prepare($query);
          }

          return $this->PreparedStatementCache[$query];
      }
 }
4

2 回答 2

2

从技术性能的角度来看,您是正确的。您将从缓存 PDOStatement 中受益(必须在同一连接中使用)。但是,在同一个 Mysql 连接和 PHP 请求中多久运行一次查询,继续执行另一个查询,然后返回到第一个查询?这似乎会让人感到困惑,并可能导致错误地更改绑定变量(如果您使用 bindParam())。

我认为你会从中找到的性能提升只是微优化,你只会增加复杂性——这不是一件好事,因为它已经足够复杂了,你需要花时间尝试清理你的循环查询以不有重叠的嵌套查询需要。

顺便说一句:仅安全性就足以成为转向准备好的陈述并投入转换时间的充分理由。

于 2013-01-07T19:56:57.853 回答
-1

我在持久层 PDO 包装类中使用了缓存的准备好的语句模式,该类包含一个“永久”绑定到查询结果的变量数组作为其成员之一。这样我就可以将其用作迭代器。

于 2020-01-25T15:13:40.200 回答