慢MySQL查询 - 如何加速?

时间:2014-09-08 06:36:09

标签: mysql sql performance

这是经过编辑的 - 我试过加快速度,但速度仍然很慢 - 请有人再提供帮助吗?

SELECT DISTINCT d.`group_ID`,
  CONCAT(u.fname, ' ', u.lname) AS uname,
  u.corp_id,
  c.`corp_name`,
  u.`user_username`,
  u.location,
  (
    SELECT email 
    FROM users 
    WHERE role = 'Level 4' 
      AND location = d.location 
      AND email NOT LIKE '%manager.%' 
    LIMIT 1
  ) AS trainer,
  u.`email`,
  GROUP_CONCAT(
    DISTINCT d.title 
    ORDER BY d.title SEPARATOR ', '
  ) AS docs 
FROM regulatory d 
  LEFT JOIN users u 
    ON u.user_id = d.`group_ID` 
    AND u.`role` = 'Level 6' 
  LEFT JOIN corporations c 
    ON c.`corp_id` = u.`corp_id` 
WHERE d.`spare1` <> 'green.gif' 
  AND u.`officialjobtitle` <> 'none' 
  AND d.`date_updated` < NOW() 
  AND (u.`corp_id` IN (1)) 
GROUP BY d.`group_ID` 
ORDER BY corp_id,
  u.`location`,
  uname ;

3 个答案:

答案 0 :(得分:1)

  • 您在其中取消了从regulatoryusers的左连接 子句,所以对这两个表使用INNER JOIN
  • 如果可能的话,
  • 对公司使用INNER JOIN(我只是不知道是否存在)
  • 删除DISTINCT。您已经在执行GROUP BY,如果正确完成,则不完全是多余的(因为它不执行GROUP BY无法执行的操作)
  • 我会尝试使用已经分组的“派生表”替换trainer的相关子查询,这样就不会将行相乘
  • 在MySQL中使用GROUP BY时,永远不会依赖“扩展”。始终指定生成唯一行所需的所有字段(就像在几乎所有其他SQL兼容的rdbms中一样)

确保在连接中涉及的所有字段上都有索引,如果可能,还要在where子句中使用这些索引。

检查解释计划。

建议编辑:

SELECT
      d.`group_ID`
    , CONCAT ( u.fname , ' ' , u.lname ) AS uname
    , u.corp_id
    , c.`corp_name`
    , u.`user_username`
    , u.location
    , MAX(l4.trainer) as trainer
    , u.`email`
    , GROUP_CONCAT(DISTINCT d.title ORDER BY d.title SEPARATOR ', ') AS docs
FROM regulatory d
INNER JOIN users u ON d.`group_ID` = u.user_id
                   AND u.`role` = 'Level 6'
LEFT JOIN corporations c ON u.`corp_id` = c.`corp_id`
LEFT JOIN (
        SELECT location, MAX(email) AS trainer
        FROM users
        WHERE ROLE = 'Level 4'
            AND email NOT LIKE '%manager.%'
        GROUP BY location
        ) l4 ON d.location = l4.location
WHERE d.`spare1` <> 'green.gif'
    AND u.`officialjobtitle` <> 'none'
    AND d.`date_updated` < NOW()
    AND u.`corp_id` IN (1)
GROUP BY
      d.`group_ID`
    , u.fname
    , u.lname
    , u.corp_id
    , c.`corp_name`
    , u.`user_username`
    , u.location
    , u.`email`
ORDER BY
      corp_id
    , u.`location`
    , uname
;

答案 1 :(得分:0)

我认为您的查询在行上几乎没有问题:

...
(
SELECT email 
FROM users 
WHERE role = 'Level 4' 
  AND location = d.location 
  AND email NOT LIKE '%manager.%' 
LIMIT 1
) AS trainer,
...

对于每一行,您都要准备单一选择。 Mayby你应该将该查询更改为另一个联接。 我还建议使用MySQL的解释功能: http://dev.mysql.com/doc/refman/5.1/en/using-explain.html

答案 2 :(得分:0)

为您在所有数据库表中的where condition中使用的所有列添加INDEX。它会加快你的所有疑问。