【问题标题】:Named parameters, caching and PDO命名参数、缓存和 PDO
【发布时间】:2010-09-27 12:37:45
【问题描述】:

如果我有这样的参数化 SQL 语句:

SELECT * FROM table WHERE my_field = :field_value

有谁知道 PDO 是否会将此(见下文)识别为相同的 SQL 语句并使用缓存而不是假设它是完全不同的 SQL 语句:

SELECT * FROM table WHERE my_field = :new_field_value

所以,我想问题是:如果参数化的 select 语句中的参数名称发生了变化,但没有其他任何变化,我还能获得缓存的性能优势吗?还是我必须确保参数名称保持不变?

【问题讨论】:

  • "SELECT *" 总是让我不寒而栗。 :-)

标签: php sql mysql pdo


【解决方案1】:

我不确定 PDO 如何处理命名参数,但如果它使用 MySQL 准备好的语句,那么如果您希望它使用查询缓存,则需要使用 MySQL 5.1.17 或更高版本。

MySQL Query Cache

在 MySQL 5.1.17 之前,prepared statements 不使用查询缓存。从 5.1.17 开始,prepared statements 在某些条件下使用查询缓存,这取决于准备方法:

【讨论】:

    【解决方案2】:

    如果您使用 PDO_MySQL,它会在服务器看到它们之前自行将准备好的语句重写为原始 SQL,除非您将 PDO::ATTR_EMULATE_PREPARES 设置为 false。

    【讨论】:

    • 这是否表明在使用具有默认属性的 PDO 时参数化对性能没有任何好处?
    • @Karim:是的,差不多。默认设置是为了使它与 MySQL 4.x 一起工作。除了没有性能提升之外,PDO 的重写器还有很多问题,并且不能很好地处理边缘情况(它破坏了我的代码几次,直到我学会将其关闭)。
    • 你有支持这个的链接吗?该手册说它利用了 mysql 4.1 或更高版本中的本机准备语句。 php.net/manual/en/ref.pdo-mysql.php
    • 该死的......即使在使用 mysqlnd 和最近的 mysql 版本的 php5.4 上,PDO::ATTR_EMULATE_PREPARES 默认情况下是打开的,除非我打开仿真,否则我的一般查询日志不会显示准备好的语句关闭。
    【解决方案3】:

    PDO 没有缓存——MySql 有。是的,它将在查询缓存中缓存“最终”查询。不仅如此,如果你多次使用相同的prepared statements,你将获得额外的速度提升,因为MySql可以缓存该语句的查询执行计划。

    【讨论】:

    • 所以你是说我用什么名字作为参数并不重要?只要查询的语法相同,我就能获得缓存的好处?
    • 不,您需要保留准备好的语句,以便重新使用它。但是您可以多次调用它,每次绑定不同的值,并从中获得一点好处。
    【解决方案4】:

    应该被识别为同一个语句,因为缓存是在查询参数被替换为值之后完成的

    【讨论】:

    • 哦,好吧。我的印象是参数化对性能很有用,因为可以完成缓存而不用担心查询中的实际值。但听起来你是在说缓存是用给定的值完成的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 2014-03-13
    • 1970-01-01
    • 2022-10-06
    • 2011-11-07
    相关资源
    最近更新 更多