我正在执行此查询
SELECT sum(c.cantitate) AS num,
produse.*,
cc.seo
FROM produse
LEFT JOIN comenzi c ON produse.id = c.produs
LEFT JOIN cosuri cs ON c.cos = cs.id
LEFT JOIN categorii cc ON produse.categorie = cc.id
WHERE cs.status = 'closed' AND produse.vizibil ='1'
GROUP BY produse.id
ORDER BY num DESC
LIMIT 14
受影响的行:0找到的行:14警告:0 1个查询的持续时间:11.734秒。
如果没有GROUP BY和,则需要16毫秒。
该查询用于基于数量销售的最畅销14产品列表。
如何重写查询以获得更好的性能?
最佳答案
也许您需要在加入之前生成总和...
每个注释要针对原始问题进行注释:
您是否想要联接到cosuri和categorii之前的粉刺总数,它们可能有多个记录导致潜在的虚高和,或者在联接之后有虚高的总和?
SELECT c.cantitate AS num,
produse.*,
cc.seo
FROM produse
LEFT JOIN (Select produs, cos, sum(cantitate) as cantitate
FROM comenzi
GROUP BY produs, cos) c ON produse.id = c.produs
LEFT JOIN cosuri cs ON c.cos = cs.id
LEFT JOIN categorii cc ON produse.categorie = cc.id
WHERE cs.status = 'closed' AND produse.vizibil ='1'
ORDER BY num DESC
LIMIT 14
例:
如果comenzi拥有ID为1的记录,且cos为'A'且参选者为3
并根据ID.A列出了3次的CS.ID加入cosuri,那么候选者的总和将被计算为3 + 3 + 3(9)而不是仅仅3 ...这可能是问题所在。如果我们预先计算总和,就可以避免出现问题(如果是一个总和),并且可以根据cosuri和categorii到comenzi的基数对值求和的开销可能是数千倍。哪个...可以提高性能。
为了确定这是否会提高性能,我们实际上需要
了解结果的要求(加入之前还是之后?)
查看一些示例数据以及每个表的统计信息,以了解记录数
表联接和任何where子句之间的索引知识
标准
数据库上的解释计划视图。
没有这些细节,我们将无法确定真正有什么帮助。一切都是没有事实的猜测;这里很少
关于mysql - GROUP BY和sum()性能问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33763282/