当前位置: 首页 > 面试题库 >

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

万勇
2023-03-14
问题内容

我在制作启用JDBC的Java应用程序时了解了预备语句,并且我的应用程序使用连接池层,这确保了预备语句在服务器端缓存,这带来了性能上的好处。

但是,对于PHP,我读过的所有内容都表明,它们仅在页面加载期间被缓存。通常,我不会多次重复同一查询,而是在给定的页面加载中运行多个不同的查询,但是会在多个页面加载中重复它们。

由于我的PHP进程是持久性的(即使用PHP-
FPM,它们将在整个生命周期中服务数百个页面,而不是一个页面),我想知道它们是否将重用数据库连接,而不是每次击中都产生并杀死它们。

  1. 将PHP-FPM与mysqli或PDO一起使用是否会使连接的时间长于单个页面加载的时间?
  2. 如果没有,我可以做到吗?
  3. 如果可以,或者我执行了#2,这将使准备好的语句的缓存持续的时间长于一页加载的时间吗?

编辑:

只是为了澄清,我不是在谈论查询缓存(完全是另一种野兽),也不是在缓存查询输出。我想在服务器端缓存已编译的准备好的语句及其执行计划。


问题答案:

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

对于通过二进制协议执行的准备好的语句,与查询缓存中的语句进行比较 是基于扩展?后的语句文本。
参数标记
。该语句仅与通过二进制协议执行的其他缓存语句进行比较。也就是说,出于查询缓存的目的,通过二进制协议发布的语句不同于通过文本协议发布的语句。

因此,如果我没记错的话,当前您将无法重新使用在php中先前请求期间准备的mysql语句。



 类似资料:
  • 根据PostgreSQL文档,准备好的语句绑定到数据库会话/连接: PREPARE创建一个prepared语句。准备好的语句是可用于优化性能的服务器端对象。执行PREPARE语句时,将解析、分析和重写指定的语句。当随后发出EXECUTE命令时,计划并执行准备好的语句。 PostgreSQL没有共享的查询计划缓存,但它有一个可选的查询计划缓存,用于准备好的语句。这意味着开发人员可以选择使用带有或不带

  • 我正在为我的sqlite日志数据库使用准备好的语句。 我的线程每50ms运行一次,将日志缓冲区中的内容写入数据库。 目前,我正在对每个线程运行一个新的准备好的语句批处理,并在所有数据线写入后关闭它们。 现在我想知道是否最好将准备好的语句保存在内存中,并仅在线程关闭/中断时关闭它? 我之所以进行这种预优化,是因为我希望这个日志线程对主应用程序性能的干扰尽可能小,我可以想象每50秒分配/解析/验证资源

  • 问题内容: 在PDO :: Prepare页上指出: “并且通过消除对参数的手动引用来帮助防止SQL注入攻击” 知道这一点,是否有一个像mysql_real_escape_string()这样的PHP函数可以照顾到PDO的转义?还是PDO会为我做好一切转义? 编辑 我现在意识到我问了一个错误的问题。我的问题确实是,“ PDO会为我做什么?” 我现在通过这些答案意识到,它实际上仅消除了对引号进行转义

  • 问题内容: 对于此查询,有必要使用吗? 任何改进或查询是否还好? 在这种情况下,查询速度很重要。 问题答案: 否,准备好的查询(正确使用时)将确保对数据进行正确的转义以进行安全查询。您有点正确地使用它们,只需要更改一件事。因为您使用的是“?” 占位符,最好通过execute方法传递参数。 请注意,如果要将其输出到页面,数据库清理并不意味着可以在HTML中安全显示,因此也可以在其上运行htmlspe

  • 其思想是创建一个准备好的语句将信息插入到用户表中,然后从生成的内容中获取insert_id以在另一个insert语句中使用 这是我的注册脚本的一个版本 第一条准备好的语句正确运行并向表中插入信息,之后成功回显$RETURNID变量。脚本中的下一个是我准备好的第二条语句,当它试图运行im时,得到的错误是: 致命错误:对第17行d:\filepath\register.php中的非对象调用成员函数bi

  • 在与甲骨文合作几年后,我刚搬到PostgreSQL。我一直在研究PostgreSQL数据库应用程序(Java、JDBC)中准备语句的一些性能问题。 Oracle在其SGA中缓存准备好的语句-准备好的语句池在数据库连接之间共享。 PostgreSQL文档似乎没有指出这一点。以下是文档中的片段(https://www.postgresql.org/docs/current/static/sql-pre