Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL查询在PHP中作为代码中的准备语句运行时运行缓慢,但通过直接MySQL查询快速运行_Php_Mysql_Go - Fatal编程技术网

MySQL查询在PHP中作为代码中的准备语句运行时运行缓慢,但通过直接MySQL查询快速运行

MySQL查询在PHP中作为代码中的准备语句运行时运行缓慢,但通过直接MySQL查询快速运行,php,mysql,go,Php,Mysql,Go,我正在调试的一个PHP应用程序在一个更大的MySQL数据库上运行了几个设计糟糕的查询 有几页确实很慢,结果证明这是因为一些查询。我开始一个接一个地检查每一个查询,尽管它们很慢,但它们本身并没有那么慢 经过进一步的调试,结果表明,只有当应用程序将它们作为准备好的语句运行时,它们才会变慢 如果我通过MySQL客户端手动运行查询,大约需要300毫秒。如果我通过MySQL客户端运行create PREADED语句,设置参数并运行它,大约需要300毫秒 如果我从PHP(mysqli)运行简单查询,大约需

我正在调试的一个PHP应用程序在一个更大的MySQL数据库上运行了几个设计糟糕的查询

有几页确实很慢,结果证明这是因为一些查询。我开始一个接一个地检查每一个查询,尽管它们很慢,但它们本身并没有那么慢

经过进一步的调试,结果表明,只有当应用程序将它们作为准备好的语句运行时,它们才会变慢

  • 如果我通过MySQL客户端手动运行查询,大约需要300毫秒。如果我通过MySQL客户端运行create PREADED语句,设置参数并运行它,大约需要300毫秒
  • 如果我从PHP(mysqli)运行简单查询,大约需要300毫秒
  • 如果我像应用程序那样通过-as-prepared语句运行它,则需要100秒
我想可能是
mysqli
,所以我用PDO尝试了一下,结果是一样的。尝试了不同的PHP版本(5.6、7.2、7.3),得到了相同的结果

所以我给了最后一次机会,写了一个小的Go脚本来测试,我得到了同样的结果,事情也有所改善

现在,如果我从MySQL客户机、MySQL工作台或PHPStorms数据库客户机运行查询的预处理语句版本,速度会很快。如果我从代码中运行查询,速度会非常快


任何关于我应该注意什么、我应该在哪里继续调试的帮助都将不胜感激。

因此,事实证明,这是由稍微不同的执行计划造成的。MySQL似乎完全基于语句创建执行计划,在通过
mysqli
PDO
使用准备好的语句时不包括参数值,这是有意义的。然而,当它提供完整的查询时,在我们的例子中,它对其中一个表进行了优化,这产生了巨大的差异

其中一个表(有550万行)在使用非prepared语句运行时有
Using join buffer(Block Nested Loop)
额外功能,而在使用prepared语句时则没有。这似乎使我们的性能相差近1000倍


我仍然不确定为什么通过PHPStorm或CLI
mysql
客户端这没有问题,我最好的猜测是,mysql中的某些API希望在准备语句时执行计划是完整的,而其他API和CLI客户端则不这样做。

因此,这是由稍微不同的执行计划造成的。MySQL似乎完全基于语句创建执行计划,在通过
mysqli
PDO
使用准备好的语句时不包括参数值,这是有意义的。然而,当它提供完整的查询时,在我们的例子中,它对其中一个表进行了优化,这产生了巨大的差异

其中一个表(有550万行)在使用非prepared语句运行时有
Using join buffer(Block Nested Loop)
额外功能,而在使用prepared语句时则没有。这似乎使我们的性能相差近1000倍


我仍然不确定为什么通过PHPStorm或CLI
mysql
客户端这没有问题,我的最佳猜测是,mysql中的某些API希望在准备语句时完成执行计划,而其他API和CLI客户端则不这样做。

检查代码,看看它是否在循环中运行查询。在编码不好的应用程序中,这种情况并不少见。一个300毫秒的查询在一个循环中运行300次需要90秒。代码与此无关。我使用了一个纯脚本,它只包含两个版本的查询和执行时间的度量。请尝试在两个位置运行查询,并查看是否存在任何可能导致问题的差异。我们使用EXPLAIN运行了两个查询,执行计划是相同的,除了一个具有
使用索引条件的表之外准备版本的额外代码。此外,查询只执行一次,循环中没有任何内容,唯一的区别是预处理语句部分。参数的数量也不多(总共9个),它们也很简单(5个整数,值为0、1和2,以及3个短字符串)。在检查性能时,很明显所有负载都在mysql中,这会使CPU达到最大值。在大多数情况下,查询都处于发送数据的状态。请检查代码以查看它是否在循环中运行查询。在编码不好的应用程序中,这种情况并不少见。一个300毫秒的查询在一个循环中运行300次需要90秒。代码与此无关。我使用了一个纯脚本,它只包含两个版本的查询和执行时间的度量。请尝试在两个位置运行查询,并查看是否存在任何可能导致问题的差异。我们使用EXPLAIN运行了两个查询,执行计划是相同的,除了一个具有
使用索引条件的表之外准备版本的额外代码。此外,查询只执行一次,循环中没有任何内容,唯一的区别是预处理语句部分。参数的数量也不多(总共9个),它们也很简单(5个整数,值为0、1和2,以及3个短字符串)。在检查性能时,很明显所有负载都在mysql中,这会使CPU达到最大值。查询大部分时间处于
发送数据
状态。