Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
准备好的语句是否使用PHP跨多个页面加载缓存到服务器端?_Php_Mysql - Fatal编程技术网

准备好的语句是否使用PHP跨多个页面加载缓存到服务器端?

准备好的语句是否使用PHP跨多个页面加载缓存到服务器端?,php,mysql,Php,Mysql,在制作支持JDBC的Java应用程序时,我了解了准备好的语句,我的应用程序使用了连接池层,确保准备好的语句被缓存在服务器端,从而提高了性能 然而,对于PHP,我读到的所有内容都表明,它们只在页面加载的生命周期内被缓存。一般来说,我不会多次重复同一个查询,而是在给定的页面负载上运行几个不同的查询,但会在多个页面负载上重复它们 由于我的PHP进程是持久性的(也就是说,它们将在其生命周期中提供数百个页面,而不是使用PHP-FPM提供一个页面),我想知道它们是否会重复使用数据库连接,而不是在每次点击时生

在制作支持JDBC的Java应用程序时,我了解了准备好的语句,我的应用程序使用了连接池层,确保准备好的语句被缓存在服务器端,从而提高了性能

然而,对于PHP,我读到的所有内容都表明,它们只在页面加载的生命周期内被缓存。一般来说,我不会多次重复同一个查询,而是在给定的页面负载上运行几个不同的查询,但会在多个页面负载上重复它们

由于我的PHP进程是持久性的(也就是说,它们将在其生命周期中提供数百个页面,而不是使用PHP-FPM提供一个页面),我想知道它们是否会重复使用数据库连接,而不是在每次点击时生成并杀死它们

  • 将PHP-FPM与mysqli或PDO结合使用会使连接保持比单个页面加载更长的时间吗
  • 如果不行,我能去吗
  • 如果是这样的话,或者我是这样做的#2,那么准备好的语句的缓存会比一个页面加载时间更长吗
  • 编辑:


    我只是想澄清一下,我不是在谈论查询缓存,它完全是另一个野兽,也不是在谈论缓存查询的输出。我想缓存已编译的prepared语句及其执行计划服务器端。

    prepared语句与结果缓存无关

    结果缓存可以通过db服务器配置进行控制,也可以通过memcached等进行强制


    我建议您研究一下,特别是对于PHP,如果您的PHP应用程序使用到数据库的连接池,并且数据库缓存准备好的语句,那么是的,缓存将在页面之间保持。如果准备好的语句缓存是由客户机库完成的,那么这就更加模糊了

    您需要查看PHP-FPM和/或PDO的文档,了解如何告诉他们使用连接池。这两者都应该有一个选择


    您应该知道,MySQL连接设置和拆卸实际上非常快,因此许多PHP安装不使用连接池。无论哪种方式,您都应该在服务器设置上投入时间,特别是
    wait\u timeout
    参数。PHP的设计理念是,当页面开始时,您可以创建所需的一切,当页面结束时,一切都会消失。大多数PHP代码和库都假设是这样。这是一个与Java完全不同的范例。

    唯一正确的答案是这取决于

    对于MySQL来说,预先准备好的语句是挑剔的野兽。有许多因素决定是否缓存准备好的语句

    一般的想法是,如果您的版本是<5.1.17,则准备好的语句永远不会缓存在查询缓存中,如果使用>=5.1.17,则取决于它

    请参阅MySQL 5.1手册中的以下页面:


    当请求被送达时,php会“清理”实例并释放资源和其他变量。这是通过几个步骤完成的。由于fastcgi在请求后使进程保持活动状态,因此并非所有步骤都被执行,也并非所有内存都被释放。例如,有一个由…使用的EG(持久列表)。。。只要进程保持活动状态,此列表就不会在请求之间清空(可能是,取决于实际实现,但这将违背EG(持久化列表)的目的)。如果您使用持久连接,您的脚本可能会在上一个请求期间建立一个“重复使用”的连接。
    要(重新)直接使用准备好的语句,您需要该语句(以及该连接)的标识符。使用(php-)postgresql时,这只是一个(连接方面的)唯一字符串,因此您的脚本可以访问另一个实例(使用相同的连接)先前准备的语句。
    使用或需要资源/对象作为语句标识符。这是一个问题,因为mysqli和pdo扩展似乎都没有提供在请求之间将资源存储在EG(persist_list)中的方法,而且您也无法重新创建它。除非php fpm提供这样的“服务”,否则直接重用mysql准备的语句似乎是不可能的。
    你所能希望的就是MySQL。在最新版本中(参见链接),它可能会在使用准备好的语句时识别该语句。但即便如此,它也不会重复使用实际准备好的声明:

    对于通过二进制协议执行的准备好的语句,与查询缓存中的语句的比较基于扩展后的语句文本?参数标记。该语句仅与通过二进制协议执行的其他缓存语句进行比较。也就是说,出于查询缓存的目的,通过二进制协议发出的语句不同于通过文本协议发出的语句。
    因此,如果我没有弄错的话,目前您不能重复使用在php中的上一个请求期间准备的mysql语句。

    在大多数情况下,php既不缓存查询,也不缓存查询结果。MySQL将执行这种缓存,无论是哪个线程或连接发出查询


    如果希望跨多个页面加载或多个服务器进行服务器端缓存,则使用MySQL查询缓存和服务器端缓存(APC、基于文件的缓存、memcached等)

    您混淆了PHP/Java层发生的事情和数据库中发生的事情

    是的,使用准备好的语句(通常)意味着执行计划由数据库本身(而不是PHP/Java层)缓存。然而,这并不意味着这总是能带来更好的性能——对此的解释需要几百页的篇幅。但是,我从您在其他地方说过的话推断,您正在使用MySQL作为DBMS,这使得讨论更加简单(IIRC没有一个存储引擎实现直方图)。通常,MySQL能够缓存足够多的关于模式的信息,以便在没有任何dis的情况下生成计划