5

group_concat在查询中添加了一个并杀死了性能。在我添加它之前和之后的解释计划是相同的,所以我对如何优化它感到困惑。

这是查询的简化版本:

SELECT @curRow := @curRow + 1 AS row_number,
docID,
docTypeID,
CASE WHEN COUNT(1) > 1
     THEN group_concat( makeID )
     -- THEN 'multiple makes found'
     ELSE MIN(makeID)
END AS makeID,
MIN(desc) AS desc
FROM simplified_mysql_table,
(SELECT @curRow := 0) r
GROUP BY docID, docTypeID,
CASE WHEN docTypeID = 1
     THEN 0
     ELSE row_number
END;

注意 中的CASE声明SELECTgroup_concat杀戮的表现。如果我评论该行并仅输出“找到多个结果”,它将执行得非常快。知道是什么原因造成的吗?

4

3 回答 3

10

在这个查询的原始非简化版本中,我们有一个DISTINCT,这是完全不必要的,并导致 group_concat 的性能问题。我不确定它为什么会导致这样的问题,但删除它可以解决性能问题。

于 2012-11-30T18:07:32.613 回答
3

在 MySQL 中,group_concat性能不应该扼杀查询性能。这是涉及字符串的额外工作,因此预计会有所放缓。但更像是 10% 而不是 10X。你能量化查询时间的差异吗?

问题:MakeID 是字符串还是整数?我想知道从整数到字符串的转换是否会影响性能。

其次,性能会是什么而concat(min(MakeId), '-', max(MakedId))不是group_concat

三、真的group_concatDISTINCTorORDER BY吗?这些可能会减慢速度,尤其是在内存有限的环境中。

于 2012-11-29T18:23:16.173 回答
0

一个想法是将查询分成两部分,一部分WHEN docTypeID = 1用于其余部分。

尝试先添加索引(docTypeID, docID, makeID, desc)

SELECT 
    docID,
    docTypeID,
    CAST(makeID AS CHAR) AS makeID,
    `desc`
FROM 
    simplified_mysql_table,
WHERE 
    NOT docTypeID = 1

UNION ALL

SELECT 
    docID,
    1,
    GROUP_CONCAT( makeID ),
    `desc`                        -- this is not standard SQL
FROM 
    simplified_mysql_table,
WHERE 
    docTypeID = 1
GROUP BY 
    docTypeID,
    docID ;
于 2012-11-29T21:23:36.417 回答