Mik*_*rov 22 php mysql performance pdo prepared-statement
我理解MySQL中预准备语句的安全性好处.这里不需要涉及这个主题.我想知道它们的性能方面.
现在,我知道当使用预准备语句的查询在单个PHP脚本中执行两次时,它更快,因为查询只被解析一次,每次查询一次.客户端进行一次准备,然后使用二进制协议发送数据两次.二进制协议速度更快,而且您不必再次进行解析.
但是,我只想在一个PHP脚本中执行一次查询的情况呢?看起来使用准备好的声明会更糟糕,因为你要两次前往服务器,一次准备,一次发送数据.只需要解析一次的好处就丢失了,你第二次旅行就受到了惩罚.如果数据的二进制格式不够小,那么使用准备好的语句会丢失,对吗?
但是,我已经阅读了一些关于PHP的mysqli或PDO库做什么的相互矛盾的报道?它们中的任何一个是否跨脚本执行缓存预准备语句?服务器是否必须在后续页面加载时再次解析预准备语句?如果答案是否定的,那么语句不必在第二个页面加载上进行解析,那么即使您每页面加载仅执行一次查询,看起来准备好的语句也会更好.
请考虑MySQL版本之间是否有任何相关变化.您可以放心地假设我使用的是PHP 5.2
编辑:只是为了说清楚,我想要专门针对MySQL和PHP的答案,指定MySQL版本,如果这是不同的,并且只考虑性能,而不是易用性或安全性.
更新:我接受了我的答案,因为后续评论有一些好主意.我仍然有点失望,似乎没有人能够回答我提出的实际问题的症结.我猜有时答案真的是"这取决于".
e4c*_*4c5 12
这是我的第一个Stackoverflow答案.自那以后发生了很多变化,特别是对mysql API的弃用和删除.即使你仍然使用php 5.6,也不应该使用mysql_*api.现在PDO或mysqli是唯一可供选择的选项.由于很多原因,PDO更好.
我读过一些关于PHP的mysqli或PDO库做什么的相互矛盾的报道?它们中的任何一个是否跨脚本执行缓存预准备语句?
页面加载之间不会使用相同的预准备语句.它必须每次都准备好.如果压缩每个大毫秒都很重要,那么存储过程可能是一个好主意(假设您有一个复杂的查询).
对于大型插入(数千行)可以通过将数据转储到文本文件并使用LOAD DATA IN FILE加载来获得更大的提升.它比一系列插件快得多.
问题的真相是,有时mysqli更快,而在其他时候mysql api更快.但差异真的很小.如果你看一下网上的任何性能测试,差异实际上只有10到20毫秒.提高性能的最佳方法是优化表格设计.
许多测试"证明"旧的api更快更方便地忘记了为了最大的安全性,应该为查询中使用的每个变量调用mysql_real_escape_string().
当且仅当查询中使用的所有表上的数据保持不变时,服务器才会缓存查询.
等待实际数字的另一次更新
小智 7
"使用准备好的陈述绝不是一个坏主意"
不对.您可以轻松填写准备好的语句缓存,max_prepared_stmt_count
如果您不知道自己在做什么,则可以超出,在使用准备好的语句的连接关闭之前,您的应用程序无效.
准备语句专门针对您的业务逻辑中的紧密内部循环而设计,您将一遍又一遍地调用相同的基本查询,这是一个参数化查询的好例子,例如:
SELECT name, address, phone from tbl WHERE id = ?
Run Code Online (Sandbox Code Playgroud)
并且每次通话都有不同的ID.这样,值得额外往返数据库进行准备,因为你可能要调用数百或数千次,只需更改参数即可.但是你应该从缓存中删除准备好的语句,或者在你的无状态脚本(php,perl,jsp,ruby等)结束时关闭连接.
如果您没有删除准备好的语句并且您正在使用连接池,则必然会随着时间的推移填满缓存并出现一个令人讨厌的错误"无法创建超过max_prepared_stmt_count语句".我是根据经验说的,所以想想你是否真的需要预备语句,因为你明确知道你将在一个紧密的循环中反复重复相同的参数化查询.
如果没有,你可能正在寻找的是让mysql使用它的基本查询缓存,这是一种与预备语句列表不同的机制,其行为就像我理解的真正的LRU缓存.
归档时间: |
|
查看次数: |
9158 次 |
最近记录: |