MySQL GROUP BY性能问题

时间:2010-01-22 18:14:27

标签: mysql performance group-by

这是我正在执行的查询(没有一些不相关的联接):

SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
GROUP BY a.id

“a”的每一行与“b”中的1到5行相关联。

问题在于GROUP BY存在性能问题(使用GROUP BY需要10倍或更多而不是使用它)。我需要在“a”中只检索每个成员的一行。

如何让它更快?

编辑:我需要能够通过a.id和/或c.id进行过滤。我应该得到的结果集是“a”的每个“有效”成员只有1行,这意味着匹配约束的行。不应返回与过滤器不匹配的行。 在我的原始查询中,这将以这种方式完成:

SELECT a.*, c.id
FROM a
LEFT OUTER JOIN b ON a.id = b.id_anunciante
LEFT OUTER JOIN c ON c.id = b.id_rubro
WHERE c.id = 1
OR a.id = 1
GROUP BY a.id

a.id,b.id_anunciante,b.id_rubro,c.id都是索引。

2 个答案:

答案 0 :(得分:5)

SELECT  a.*,
        (
        SELECT  c.id
        FROM    b
        JOIN    с
        ON      c.id = b.id_rubro
        WHERE   b.id_anunciante = a.id
        -- add the ORDER BY condition to define which row will be selected.
        LIMIT 1
        )
FROM    a

b (id_anunciante)上创建索引,以便更快地运行。

<强>更新

此处不需要OUTER JOINs

重写您的查询:

SELECT  a.*, c.id
FROM    a
JOIN    b
ON      b.id_anunciante = a.id
JOIN    c
ON      c.id = b.id_rubro
WHERE   a.id = 1
UNION ALL
SELECT  a.*, 1
FROM    a
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    c
        JOIN    b
        ON      b.id_rubro = c.id
        WHERE   c.id = 1
                AND b.id_anunciante = a.id
        )

答案 1 :(得分:0)

添加ORDER BY NULL以避免MySQL在执行分组时进行的隐式排序。

我想你在a.id,b.id_anunciante,b.id_rubro和c.id上有索引/ PK?如果您的mysql版本无法进行索引合并,我想您可以尝试在(b.id_anunciante,b.id_rubro)上添加复合索引。