当前位置: 首页 > 面试题库 >

PHP运行查询所需的时间比MySQL客户端长90倍

仲孙翔飞
2023-03-14
问题内容

我正在通过命令行PHP脚本运行mysql查询(使用mysqlnd驱动程序上的PDO进行预查询)。这是一个简单的查询,只有一个左联接,返回100行,每行返回7小列。

当我在MySQL CLI中(在运行有问题的PHP脚本的同一台计算机上)运行此查询时,它花费了0.10秒-即使抛出了SQL_NO_CACHE标志。

当我运行此查询时,通过PDO进行准备需要9秒钟以上。这 是execute()-不包括提取调用所需的时间。

我的查询示例:

SELECT HEX(al.uuid) hexUUID, al.created_on,
    IFNULL(al.state, 'ON') actionType, pp.publishers_id publisher_id,
    pp.products_id product_id, al.action_id, al.last_updated
FROM ActionAPI.actionLists al
LEFT JOIN ActionAPI.publishers_products pp
    ON al.publisher_product_id = pp.id
WHERE (al.test IS NULL OR al.test = 0)
    AND (al.created_on >= :since OR al.last_updated >= :since)
ORDER BY created_on ASC
LIMIT :skip, 100;

考虑到我尝试过的每个本机MySQL客户端都几乎立即运行了该查询,因此我不认为该查询有问题,但是以下是有关踢的解释:

+----+-------------+-------+--------+-------------------------+------------+---------+-----------------------------------+------+-------------+
| id | select_type | table | type   | possible_keys           | key        | key_len | ref                               | rows | Extra       |
+----+-------------+-------+--------+-------------------------+------------+---------+-----------------------------------+------+-------------+
|  1 | SIMPLE      | al    | index  | created_on,last_updated | created_on | 8       | NULL                              |  100 | Using where |
|  1 | SIMPLE      | pp    | eq_ref | PRIMARY                 | PRIMARY    | 4       | ActionAPI.al.publisher_product_id |    1 |             |
+----+-------------+-------+--------+-------------------------+------------+---------+-----------------------------------+------+-------------+
2 rows in set (0.00 sec)

PDO到底在做什么,耗时8.9秒?

编辑:
正如评论中所述,我也已经编写了mysql_query版本,它具有同样的不良性能。但是,删除WHERE子句的一部分,使其运行速度与MySQL客户端一样快。请继续阅读以获取令人难以置信的详细信息。


问题答案:

提供有关此问题的最新信息:

我还没有找到原因,但是事实证明,PHP和CLI的解释是不同的。我不确定连接的任何方面是否会导致MySQL选择对索引使用不同的字段,因为据我所知,这些东西不应该相关。但是可惜,PHP的EXPLAIN显示未使用正确的索引,而CLI却在使用。

在这种(令人困惑的)情况下,解决方案是使用索引提示。从我的示例中看到此修改后的查询中的“ FROM”行:

SELECT HEX(al.uuid) hexUUID, al.created_on,
    IFNULL(al.state, 'ON') actionType, pp.publishers_id publisher_id,
    pp.products_id product_id, al.action_id, al.last_updated
FROM ActionAPI.actionLists al USE INDEX (created_on)
LEFT JOIN ActionAPI.publishers_products pp
    ON al.publisher_product_id = pp.id
WHERE (al.test IS NULL OR al.test = 0)
    AND (al.created_on >= :since OR al.last_updated >= :since)
ORDER BY created_on ASC
LIMIT :skip, 100;

希望这对某人有帮助!



 类似资料:
  • 我有以下PHP代码在Laravel正在执行一个MySql查询: 执行此查询需要很长时间。 我对所排序的列以及其他查询的许多列都有索引。 我该怎么办? 更新: 执行的查询: 结果:

  • 当我在查询浏览器和我的应用程序中运行相同的查询时,我会得到很大的时间差。查询浏览器运行查询只花了2秒。但在我的应用程序中,它需要20秒。实际上,我正在处理12L的记录。我使用的是sql server数据库,在我的应用程序中使用了本机sql(JDBC)API。我指的是natve语句和resultSet API来获取记录。我在这里复制了我的代码片段。 另外,我使用了相同的查询条件与相同的用户。 我的代

  • 我知道要冬眠。我有一个sql语句 我尝试用createCriteria和HQL实现它。 HQL: 问题是,此HQL的执行时间延长了10倍。并执行许多不必要的查询。我尝试使用注释字符串进行转换,它有了一些改进,但仍然比createCriteria查询长5倍,此外,我无法进行此转换 <代码>列表 版本数据防御

  • 问题内容: 说我长时间运行更新查询 some_table中的modification_time的值是什么?它们是相同还是不同(例如,执行查询花了2天的时间)。 如果它们不同,如​​何编写此查询以使它们都相同? 问题答案: 它们都是一样的,因为NOW()在查询开始时被锁定了。 答案太短了吗? 好的,更多信息有关NOW()的MySQL参考 NOW()返回一个 恒定时间 ,该时间指示该语句 开始执行的时

  • 没有一个参数帮助我们在较短的时间内解决查询。

  • 我目前使用的是mysql 我有两个名为person和zim_list_id的表,这两个表都有超过200万行