dsa5211314 2019-06-30 17:07
浏览 128

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

A PHP application I’m trying to debug runs several badly designed queries on a bigger MySQL database.

A few pages are really slow and it turned out that it is because of a few queries. I started to check every query one by one and though they are slow they are not that slow on their own.

After some further debugging it turned out that they are only slow when they are being run by the application as prepared statements.

  • If I run the query by hand via MySQL client it takes about 300 ms. If I run create a prepared statement via MySQL client and set the parameters and run it, it takes about 300 ms.
  • If I run the simple query from PHP (mysqli) it takes about 300 ms.
  • If I run it like the application does—via mysqli—as prepared statement it takes 100 seconds.

I thought maybe it's mysqli so I tried it with PDO, the result is the same. Tried different PHP versions (5.6, 7.2, 7.3) and get the same result.

So I gave a last chance and wrote a small Go script to test, and I get the same results and things improved.

Now if I run the prepared statement version of the query from MySQL client or MySQL Workbench or PHPStorms Database client it's fast. And if I run the query from code it's freaking fast.

Any help would be really appreciated about what should I look after, where should I continue my debugging.

  • 写回答

1条回答 默认 最新

  • doushantun0614 2019-07-01 08:00
    关注

    So as it turns out, this was caused by a slightly different execution plan. MySQL seems to create the execution plan purely based on the statement, not including the parameter values when using prepared statements via mysqli or PDO , which kind of makes sense. However when it's provided with the full query, in our case it introduced an optimisation on one of the tables which made a huge difference.

    One of the tables (with 5.5 million rows) had the Using join buffer (Block Nested Loop) Extra on it when running with the non prepared statement, while with the prepared statement it didn't. This seems to have made a close to 1000x performance difference for us.

    I am still not sure why this has not an issue via PHPStorm or the CLI mysql client, my best guess is, that certain APIs in MySQL expect the execution plan to be complete when a statement is prepared, while other APIs, and the CLI client don't.

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)