准备好的陈述如何运作?

5 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";
Run Code Online (Sandbox Code Playgroud)

Mik*_*one 3

据我了解,如果是相同的语句,准备好的语句将重用生成的 SQL 计划,因此数据库将看到相同的准备好的语句,而不必执行找出如何查询数据库的工作。我想说,保存准备好的语句的额外工作Product::getPrice_A通常不是很有帮助,更多的是因为它会使代码变得模糊,而不是性能问题。在处理性能时,我认为最好始终关注代码的清晰度,然后当您有表明问题的真实统计数据时才关注性能。

我会说“是的,额外的工作是不必要的”(无论它是否真的提高了性能)。另外,我不是一个非常大的数据库专家,但是准备好的语句的性能增益是我从其他人那里听说的,并且它是在数据库级别,而不是代码级别(因此,如果代码实际上在调用参数化语句)实际的数据库,那么数据库可以执行这些执行计划缓存...尽管根据数据库,即使没有参数化语句,您也可能会受益)。

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