准备好的陈述如何运作?

时间:2008-09-10 18:41:19

标签: php sql pdo

我正在编写一些数据库例程,我正在使用预处理语句。我的环境是PHP5的PDO。

我理解预处理语句主要提供性能优势,以及一些辅助奖励,例如无需手动SQL转义输入数据。

我的问题是性能部分。

我在下面有两个getPrice函数的实现,它接受一个产品ID并返回它的价格。

getPrice_A在同一脚本执行中的后续调用中重用相同的PDOStatement对象。这是必要的还是推荐的?如果是这样,有没有办法避免在每个模型中的每个get *()中重复这些额外的代码?

getPrice_B在每次调用时都会创建一个新的PDOStatement对象。 DBMS是否会认识到这个陈述已经准备好了,仍然可以跳过一些工作?换句话说,这种实现是否恰当地利用了预处理语句的性能优势?

写完所有这些并阅读之后,我认为getPrice_B很好,getPrice_A提供了一个可以忽略不计的好处,这可能是也可能不值得额外的复杂化。

我仍然希望听到更有知识的人的确定。

假设$pdo是以下示例中有效的,已连接的PDO对象。

<?php
class Product {
    static function &getPrice_A($id) {
        static $stmt;
        if (!$stmt) {
            $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?');
        }
        $stmt->execute(array($id));
        return $stmt->fetchColumn(0);
    }

    static function &getPrice_B($id) {
        $stmt = $pdo->prepare('SELECT price FROM products WHERE id = ?');
        $stmt->execute(array($id));
        return $stmt->fetchColumn(0);
    }
}

// example usage:
$price = Product::getPrice(4982);
echo "Product 4982 costs $price\n";

1 个答案:

答案 0 :(得分:3)

根据我的理解,如果生成的SQL计划是相同的语句,那么预处理语句将重用生成的SQL计划,因此数据库将看到相同的预处理语句,而不必执行工作来弄清楚如何查询数据库。我想说在Product::getPrice_A中保存预准备语句的额外工作通常不是很有用,更多的是因为它可能会掩盖代码而不是性能问题。在处理性能时,我觉得最好关注代码清晰度,然后在有真实的统计信息表明问题时再进行性能。

我会说“是的,额外的工作是不必要的”(无论它是否真的提升了性能)。此外,我不是一个非常大的数据库专家,但是我从其他人那里听到了预处理语句的性能提升,它是在数据库级别,而不是代码级别(所以如果代码实际上是在调用参数化语句,那么实际的数据库,然后数据库可以执行这些执行计划缓存...虽然取决于数据库,即使没有参数化语句,您也可以获得好处。)

无论如何,如果你真的担心(和看到)数据库性能问题,你应该研究一个缓存解决方案......我强烈推荐memcached。使用这样的解决方案,您可以缓存查询结果,甚至不会访问数据库以查找经常访问的内容。