查询执行时间超过40秒

时间:2017-12-11 09:32:11

标签: mysql sql

此查询需要超过40秒才能在具有200万行

的表上执行
user = getAllUser()

我知道这是因为查询中的计数,但我怎么能有效地解决这个问题。

编辑:解释

enter image description here

感谢。

2 个答案:

答案 0 :(得分:1)

使用GROUP BY代替

SELECT my_robots.*, 
       count(id) as openorders, 
       apikeys.apikey, 
       apikeys.apisecret 
FROM my_robots
JOIN apikeys ON apikeys.id = my_robots.idApiKey
LEFT JOIN hpsi_trading ON hpsi_trading.idRobot = my_robots.id and estado <= 1
WHERE estado <= 1 and 
      idRobot = '2' and 
      ready = '1' and 
      (
          my_robots.id LIKE '%0' OR 
          my_robots.id LIKE '%1' OR 
          my_robots.id LIKE '%2'
      ) 
GROUP BY my_robots.id, apikeys.apikey, apikeys.apisecret

使用显式JOIN语法。需要一些索引来快速运行它,但是,您的帖子(以及您的查询)中的数据库结构也不清楚。

答案 1 :(得分:0)

解释计划显示最大的痛苦是从表 hpsi_trading 中选择数据。

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

使用JOIN + GROUP BY替换此子查询将需要MySQL在所有这些记录之间加入(膨胀),然后才使用GROUP BY对数据进行收缩,这可能需要一些时间。

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

到目前为止,它是所有专业人士。但是,这里的问题是将子查询提取到临时表可能需要在开发方面付出更多努力。

请尝试使用此版本并告知我们是否有帮助(如果没有,请提供新的EXPLAIN计划截图):

创建临时表:

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')

为此解决方案添加的索引(我从逻辑中假设 estado idRobot ready 来自apikeys表。如果那样& #39;不是这样,让我知道,我会调整索引):

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`);