如何优化这个mysql查询?运行缓慢

时间:2013-01-03 15:35:24

标签: mysql sql

我正在使用的数据库,imho,设计不好,但也许只是我不理解它。无论如何,我有一个查询,提取正确的信息,但它确实减慢了我的PHP脚本。我希望有人可以看看这个并让我知道嵌套查询到这个深度是否错误,以及是否有办法从下面的sql语句中描述的关系简化查询。

SELECT name 
FROM groups 
WHERE id = (SELECT DISTINCT immediateparentid 
            FROM cachedgroupmembers 
            WHERE groupid = (SELECT  g.id AS AdminCc
                             FROM Tickets t, groups g  
                             WHERE t.Id = 124 AND t.id = g.instance AND g.type = 'AdminCc')
                             AND immediateparentid <> (SELECT  g.id AS AdminCc
                                                       FROM Tickets t, groups g  
                                                       WHERE t.Id = 124 AND t.id = g.instance AND g.type = 'AdminCc'))

请帮忙

更新:

以下是使用Explain的输出 Explain

您可能需要右键单击并选择“查看图像”才能使文本清晰。

3 个答案:

答案 0 :(得分:1)

据我所知,你可以消除一个子选择。

SELECT name 
FROM groups 
WHERE id = (
    SELECT DISTINCT immediateparentid 
    FROM cachedgroupmembers 
    WHERE groupid = (
        SELECT g.id 
        FROM Tickets t, groups g
        WHERE t.Id = 124 AND t.id = g.instance AND g.type = 'AdminCc'
    ) AND immediateparentid != groupid
)

答案 1 :(得分:1)

我更习惯在Oracle上使用PL / SQL,但我会试一试。

  1. 摆脱别名,你不需要它们。
  2. 确保where子句中使用的列已编入索引(t.Idg.type)。
  3. 不知道MySQL是否默认索引外键,但值得检查。
  4. 您可以像这样缩短SQL代码:

    SELECT name 
    FROM groups 
    WHERE id = (
        SELECT DISTINCT immediateparentid 
        FROM cachedgroupmembers 
        WHERE groupid = (
            SELECT g.id 
            FROM Tickets t, groups g
            WHERE t.Id = 124 AND t.id = g.instance AND g.type = 'AdminCc'
       ) AND immediateparentid != groupid
    )
    

    或:

     SELECT name 
        FROM groups 
        WHERE id = (
            SELECT DISTINCT immediateparentid 
            FROM cachedgroupmembers 
            WHERE groupid = (
                SELECT g.id 
                FROM Tickets t inner join groups g on t.id = g.instance
                WHERE t.Id = 124 AND g.type = 'AdminCc'
     ) AND immediateparentid != groupid
    )
    

答案 2 :(得分:0)

如果您的票证表很大,您可以考虑临时表而不是查询它两次