在类包装器中缓存PDO准备语句

时间:2013-01-07 19:47:27

标签: php mysql pdo prepared-statement

我正在将旧的(杂乱的)代码从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];
      }
 }

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:-1)

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