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没有错误=no
close()
需要:

$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