我在创建支持JDBC的Java应用程序时学习了预处理语句,而我的应用程序使用连接池层来确保预准备语句在服务器端缓存,这样可以获得性能优势.
但是,对于PHP,我读过的所有内容都说它们只是在页面加载的生命周期中被缓存.通常,我不会多次重复相同的查询,但在给定的页面加载上运行几个不同的查询,但会在多个页面加载中重复它们.
由于我的PHP进程是持久的(即它们将在其生命周期中使用数百页而不是仅使用PHP-FPM),我想知道它们是否会重新使用数据库连接,而不是为每次命中生成并终止它们.
编辑:
只是为了澄清,我不是在谈论查询缓存,它完全是另一个野兽,或者缓存查询的输出.我想缓存已编译的预准备语句及其执行计划服务器端.
Vol*_*erK 12
当提供请求时,php"清理"实例并释放资源和其他变量.这是通过几个步骤完成的.由于fastcgi在请求之后保持进程处于活动状态,并非所有步骤都被执行,并且并未释放所有内存.有例如由mysql_pconnect(),pg_pconnect()使用的EG(persistent_list),......只要进程保持活动状态,这个列表就不会在请求之间清空(可能是,取决于实际的实现,但是无视EG(persistent_list)的目的.如果使用持久连接,则脚本可能会在先前的请求期间建立"重用"连接.
要(重新)直接使用预准备语句,您需要该语句的标识符(以及该连接).当使用(php-)postgresql时,这只是一个传递给pg_execute()的(连接方式)唯一字符串,因此您的脚本可以访问之前由另一个实例准备的语句(使用相同的连接).
使用mysqli或PDO-mysql,您需要一个资源/对象作为语句标识符.这是一个问题,因为mysqli和pdo扩展似乎都没有提供在请求之间将资源存储在EG(persist_list)中的方法,也无法重新创建它.除非php-fpm提供这样的"服务",否则似乎不可能直接重用mysql预处理语句.
您可以期待的是MySQL的服务器端查询缓存.在最近的版本中(参见链接),它可以在使用预准备语句时识别语句.但即便如此,它也不会重复使用实际准备好的声明:
对于通过二进制协议执行的预处理语句,与查询缓存中的语句进行比较是基于扩展后的语句文本?参数标记.该语句仅与通过二进制协议执行的其他缓存语句进行比较.也就是说,对于查询缓存目的,通过二进制协议发出的语句与通过文本协议发出的语句不同.
所以,如果我没有弄错的话,目前你不能重新使用在php中的先前请求中准备的mysql语句.