Php 快速/最佳实践刷新mysqli_多_查询()
当塞巴斯蒂安说他正在断开和重新连接每次使用Php 快速/最佳实践刷新mysqli_多_查询(),php,mysqli,benchmarking,mysqli-multi-query,Php,Mysqli,Benchmarking,Mysqli Multi Query,当塞巴斯蒂安说他正在断开和重新连接每次使用mysqli\u multi\u query()@之间的连接时,我退缩了,因为这似乎不是最佳做法 然而,Craig@在他的案例中指出,在每次使用mysqli\u multi\u query()时断开和重新连接要比使用mysqli\u next\u result()更快 我想问一下,当程序员应该选择“新连接”而不是“下一个结果”方法时,是否有人有进一步的第一手知识或基准证据来建议近似的“中断”(基于查询量或其他方面) 我也很高兴听到与速度无关的任何/所有问
mysqli\u multi\u query()
@之间的连接时,我退缩了,因为这似乎不是最佳做法
然而,Craig@在他的案例中指出,在每次使用mysqli\u multi\u query()
时断开和重新连接要比使用mysqli\u next\u result()更快
我想问一下,当程序员应该选择“新连接”而不是“下一个结果”方法时,是否有人有进一步的第一手知识或基准证据来建议近似的“中断”(基于查询量或其他方面)
我也很高兴听到与速度无关的任何/所有问题。克雷格使用连接功能对速度有影响吗
克雷格的while语句之间是否存在速度差异:
while ($mysqli->next_result()) {;}
-对-
我建议的一个while语句:
while(mysqli_more_results($mysqli) && mysqli_next_result($mysqli));
-对-
在运行第一个多\u查询之前,为每个预期的多\u查询创建一个新连接。我刚刚测试了这一点,两个mysqli\u multi\u query()
s没有错误=noclose()
需要:
$mysqli1=mysqli_connect("$host","$user","$pass","$db");
$mysqli2=mysqli_connect("$host","$user","$pass","$db");
-对-
在每个mysqli\u multi\u query()
之间打开和关闭,如Sebastien和Craig:
$mysqli = newSQL();
$mysqli->multi_query($multiUpdates);
$mysqli->close();
-对-
任何人都有另一个测试选项?这不是下一个结果()
的错,而是他们自己的问题。代码运行所需的时间取决于实际查询执行所需的时间
虽然mysqli\u multi\u query()
返回控制的速度相当快,这并不意味着所有查询都在那个时候执行。相反,当mysqli\u multi\u query()
完成时,只执行了第一个查询。而所有其他查询都在mysql端排队等待异步执行
由此您可以得出结论,调用本身并没有添加任何超时,它只是在等待下一个查询完成。如果查询本身需要时间,那么next\u result()
也必须等待
知道你已经知道该选择哪种方式:如果你不在乎结果,你可以关闭连接。但事实上,这只不过是在地毯下扫除灰尘,让所有缓慢的查询留在原地。因此,最好保持next_result()
循环(特别是因为您必须检查错误/受影响的行等),但要加快查询本身的速度
因此,要解决next_result()
的问题,实际上必须解决查询速度的常规问题。因此,以下是一些建议:
对于select查询,通常使用索引/解释分析,其他答案中已经解释过
对于DML查询,尤其是成批运行的查询,还有其他方法:
说到Craig的案例,它非常类似于innodb写入速度的已知问题。默认情况下,innodb引擎设置为非常谨慎的模式,在引擎确保成功完成前一次写入之前,不会执行后续写入。因此,它使得写入速度非常慢(大约只有10次查询/秒)。常见的解决方法是一次完成所有写入操作。对于插入查询,有很多方法:
- 可以使用多值插入语法
- 可以使用“加载数据填充查询”
- 您可以在事务中包装所有查询
而对于只更新和删除事务仍然是可靠的方式。因此,作为一种通用解决方案,可以提供这种变通方法
$multiSQL = "BEGIN;{$multiSQL}COMMIT;";
$mysqli->multi_query($multiSQL);
while ($mysqli->next_result()) {/* check results here */}
如果它在您的情况下不起作用/不适用,那么我建议更改mysqli\u multi\u query()
对于循环中运行的单个查询,调查并优化速度,然后返回multi\u query。回答您的问题:
三思而后行
我希望你的mysqli\u more\u results()
调用(跳转前的查看)不会加快速度:如果你有n个结果,你将对数据库进行(2*n)-1次调用,而Craig则进行n+1次调用
多重连接
multi\u query
,因此您只需增加连接开销
打开和关闭数据库
听;-)但不要忘记你在做什么。将查询包装到事务中,将使其成为事务。这意味着,他们要么都失败,要么都成功。有时,这是使数据库永远不会与你的论述领域发生冲突所必需的。但使用事务加速可能会产生不必要的副作用。考虑一个查询违反约束的情况。这将使整个交易失败。这意味着,如果它们最初不是一个逻辑事务,并且大多数查询都应该成功,那么您必须找出哪些错误,哪些必须重新发布。花费更多,而不是加速
的查询实际上看起来应该是某个更大事务的一部分,该事务包含父级的删除或更新
相反,试着记住
没有勺子
在您的示例中,不需要多个查询。该表单采用多个元组作为值。因此,不要准备一个已准备好的语句并将其重复执行打包到事务中。您可以准备一条语句,并让它执行和自动提交。这样可以节省大量往返时间
因此,制作以下形式的SQL语句:
INSERT INTO r (a, b, c) VALUES (?, ?, ?), (?, ?, ?), ...
绑定并执行它mysqldump
可以,我们为什么不呢?mysql参考手册作为一个参考。在其DML部分中查找insert和update查询。但是理解为什么--opt
会这样做是一个好的开始
准备一份声明的价值被低估了
对我来说,预处理语句的真正价值不在于可以多次执行它们,而在于自动输入转义。对于一个微不足道的额外客户机-服务器往返,您可以避免使用SQLI