【问题标题】:Should prepared statement ever be used without placeholders是否应该在没有占位符的情况下使用准备好的语句
【发布时间】:2016-12-11 19:45:26
【问题描述】:

显然没有 SQL 注入的威胁,但是如果没有变量插入到准备好的语句中,使用准备好的语句而不是 query() 是否有任何性能考虑?

$sql='SELECT t1.a,t1.b,t2.c FROM t1 INNER JOIN t2 ON t2.id=t1.t2_id';
$stmt=$db->prepare($sql);
while(true) {
  ...
  //Should this be used
  $stmt->execute();
  //or this, and get rid of the above prepared statement?
  $rs=$db->query($sql);

  $rs=$stmt->fetchAll();
  ...
}

编辑。 lonesomeday 和 Your Common Sense 的答案相互矛盾,但都是正确的,因为我没有说明我是否正在使用仿真模式。但是,我认为此时从根本上编辑原始问题对我来说并不合适,并且希望我可以同时选择这两个...

【问题讨论】:

  • 您说您使用的是PDO::ATTR_EMULATE_PREPARES => false,所以您没有使用仿真模式。
  • @YourCommonSense 我知道我没有使用仿真模式,但我没有在原帖中这么说。

标签: php mysql pdo prepared-statement


【解决方案1】:

在这种精确的情况下,是的,因为您正在循环。

通过使用准备好的语句,您只需将查询发送到 MySQL 一次,并且只解析一次。如果每次只发送 SQL,它必须重新解析它,而不是重复使用相同的代码。

在循环中,您正在多次重新执行查询,因此(微观上)使用相同的 SQL 语句更有效。

【讨论】:

    【解决方案2】:

    没有应该,但出于常识,对不包含占位符的查询使用query() 方法是一个合理的想法。

    但是,如果您在关闭emulation mode 的情况下使用 PDO,则上述内容是有意义的。否则,准备/执行对将像单个 query() 调用一样生效。

    但是,鉴于建议关闭仿真模式,我会以这种方式实现一个简单的 PDO 包装器

    class MyPDO extends PDO
    {
        public function run($sql, $args = NULL)
        {
            if (!$args) return $this->query($sql);
            $stmt = $this->prepare($sql);
            $stmt->execute($args);
            return $stmt;
        }
    }
    

    显然,另一个答案中提到了一个案例,但我几乎无法想象可以使用它的案例。

    【讨论】:

    • 我的典型 PDO 配置使用 [ PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]
    • 因此在这种情况下, query() 而不是 prepare 将为您节省到数据库的往返时间。差异被认为可以忽略不计,但好吧,只是为了它。
    • @YourCommonSense 平心而论,我也无法想象使用它。看起来就像问题中提出的问题一样。
    • @lonesomeday 如果你盲目相信开场海报,你会发现伊利湖里有龙。还有美人鱼。我仍然在发布的代码中看不到任何意义。你?此外,虽然你们更喜欢对某些 OP 奴性,但我的目标是更广泛的受众,因此更普遍的答案。
    • @YourCommonSense 有一个美好的一天。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    相关资源
    最近更新 更多