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

标签 php mysql go

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

有几个页面真的很慢,原来是查询次数少的缘故。我开始一个一个地检查每个查询,虽然它们很慢,但它们本身并没有那么慢。

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

  • 如果我通过 MySQL 客户端手动运行查询,大约需要 300 毫秒。如果我通过 MySQL 客户端运行 create a prepared statement 并设置参数并运行它,大约需要 300 毫秒。
  • 如果我从 PHP (mysqli) 运行简单查询,大约需要 300 毫秒。
  • 如果我像应用程序那样运行它——通过 mysqli —作为准备好的语句,它需要 100 秒。

我想可能是mysqli 所以我用PDO试了一下,结果是一样的。尝试了不同的 PHP 版本(5.6、7.2、7.3)并得到相同的结果。

所以我给了最后一次机会并编写了一个小的 Go 脚本进行测试,我得到了相同的结果并且改进了一些东西。

现在,如果我从 MySQL 客户端或 MySQL Workbench 或 PHPStorms 数据库客户端运行查询的准备语句版本,它会很快。如果我从代码运行查询,它会非常快。

对于我应该注意什么,我应该在哪里继续调试,我们将不胜感激。

最佳答案

事实证明,这是由略有不同的执行计划引起的。 MySQL 似乎完全基于语句创建执行计划,不包括通过 mysqliPDO 使用准备好的语句时的参数值,这是有道理的。然而,当它提供了完整的查询时,在我们的例子中它引入了对其中一个表的优化,这产生了巨大的差异。

其中一个表(有 550 万行)在使用非准备语句运行时有 Using join buffer (Block Nested Loop) Extra,而使用准备语句则没有.这似乎为我们带来了近 1000 倍的性能差异。

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

关于php - 当在代码中作为准备好的语句运行时,MySQL 查询在 PHP 中运行缓慢,但通过直接 MySQL 查询运行速度很快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56826859/

相关文章:

MySql 选择最大 ID 错误?

Docker 和文件锁定

Golang 使用数据进行 GET 请求

php - 使用 Or-Tools 的车辆路径问题 - 自动决定初始起点

javascript - 在头文件顶部导航中使用 AJAX Search Lite 插件 - WordPress

MySQL 不允许我使用数据类型 INT 插入超过 10 个数字

go - 优雅地停止被阻塞的 goroutine

php - PHP 中 FOR 与 FOREACH 的性能

php - 使用 Google Translate 在 PHP 中进行文字转语音

php - 如何在CodeIgniter框架中将图像上传到文件夹并插入到数据库