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

问题描述 投票:3回答:2

我正在将旧的(混乱的)代码从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];
      }
 }
php mysql pdo prepared-statement
2个回答
1
投票

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

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

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.