Mysql 查询的执行时间超过40秒

Mysql 查询的执行时间超过40秒,mysql,sql,Mysql,Sql,在一个有200k行的表上执行此查询需要40秒以上 SELECT my_robots.*, ( SELECT count(id) FROM hpsi_trading WHERE estado <= 1 and idRobot = my_robots.id ) as openorders, apikeys.apikey, apikeys.apisecret FROM my_robots

在一个有200k行的表上执行此查询需要40秒以上

SELECT 
     my_robots.*, 
     (
        SELECT count(id) 
        FROM hpsi_trading 
        WHERE estado <= 1 and idRobot = my_robots.id
     ) as openorders,
     apikeys.apikey, 
     apikeys.apisecret 
FROM my_robots, apikeys 
WHERE estado <= 1 
     and idRobot = '2' 
     and ready = '1' 
     and apikeys.id = my_robots.idApiKey 
     and (my_robots.id LIKE '%0' 
          OR my_robots.id LIKE '%1' 
          OR my_robots.id LIKE '%2') 
我知道这是因为查询中的计数,但我如何才能有效地解决这个问题

编辑:解释

谢谢。

改用分组方式


使用显式连接语法。需要一些索引才能快速运行,但是,从您的帖子和查询中还不清楚数据库结构。

解释计划显示,最大的痛苦是从hpsi_交易表中选择数据

从数据库的角度来看,挑战在于查询在SELECT子句中包含一个相关子查询,在过滤之后,需要对外部查询的每个结果执行一次

用JOIN+GROUP BY替换此子查询将需要MySQL在所有这些记录之间进行连接,然后使用GROUP BY对数据进行膨胀,这可能需要时间

相反,我会将子查询提取到一个临时表中,该临时表在创建过程中分组,为其编制索引并连接到它。这样,子查询将运行一次,使用快速覆盖索引,它将已经对数据进行分组,然后将其连接到另一个表

到目前为止,一切都是专业的。但是,这里的缺点是将子查询提取到临时表可能需要在开发方面付出更多的努力

请尝试此版本,并让我知道它是否有帮助如果没有,请提供一个新的解释计划屏幕截图:

创建临时表:

CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS 
      SELECT idRobot, COUNT(id) as openorders
      FROM   hpsi_trading
      WHERE  estado <= 1
      GROUP BY idRobot;

显示explain your query.edited的输出。在explain中,使用两个FROM子句是不可取的。使用内部联接代替。您还可以预先限定所有表.列引用。Estado,idRobot,准备在表关联myRObots中防止歧义和猜测,apikeyssmall注释-在ready='1'附近有一个额外的'and'运算符。试图编辑答案,但需要修改至少6个字符。。。
CREATE TEMPORARY TABLE IF NOT EXISTS temp1 AS 
      SELECT idRobot, COUNT(id) as openorders
      FROM   hpsi_trading
      WHERE  estado <= 1
      GROUP BY idRobot;
SELECT 
    my_robots.*,
    temp1.openorders,
    apikeys.apikey,
    apikeys.apisecret
FROM
    my_robots,
    apikeys
    LEFT JOIN temp1 on temp1.idRobot = my_robots.id
WHERE
    estado <= 1 AND idRobot = '2'
        AND ready = '1'
        AND apikeys.id = my_robots.idApiKey
        AND (my_robots.id LIKE '%0'
        OR my_robots.id LIKE '%1'
        OR my_robots.id LIKE '%2')
ALTER TABLE `temp1` ADD INDEX `temp1_index_1` (idRobot);
ALTER TABLE `hpsi_trading` ADD INDEX `hpsi_trading_index_1` (idRobot, estado, id);
ALTER TABLE `apikeys` ADD INDEX `apikeys_index_1` (`idRobot`, `ready`, `id`, `estado`);
ALTER TABLE `my_robots` ADD INDEX `my_robots_index_1` (`idApiKey`);