我在具有order by
和group by
的查询中遇到性能问题。我已经在SO上检查了类似的问题,但没有找到解决方案:(
我的数据库架构中有这样的内容:
pattern
有许多pattern_file
属于project_template
,属于project
现在,我想通过某些数据(我加入的其他表)过滤projects
,并希望得到结果,例如按projects.priority
排序并按patterns.id
分组。我已经尝试了很多事情,并且想得到想要的结果,但我想出了这个查询:
SELECT DISTINCT `projects`.* FROM `projects`
INNER JOIN `project_templates` ON `project_templates`.`project_id` = `projects`.`id`
INNER JOIN `pattern_files` ON `pattern_files`.`id` = `project_templates`.`pattern_file_id`
INNER JOIN `patterns` ON `patterns`.`id` = `pattern_files`.`pattern_id`
...[ truncated ]
INNER JOIN (SELECT DISTINCT projects.id FROM `projects` INNER JOIN `project_templates` ON `project_templates`.`project_id` = `projects`.`id`
INNER JOIN `pattern_files` ON `pattern_files`.`id` = `project_templates`.`pattern_file_id`
INNER JOIN `patterns` ON `patterns`.`id` = `pattern_files`.`pattern_id`
...[ truncated ]
WHERE [here my conditions] ORDER BY [here my order]) P
ON P.id = projects.id
WHERE [here my conditions]
GROUP BY patterns.id
ORDER BY [here my order]
根据我的研究,我必须使用子查询INNER JOIN
来解决问题“在分组之前先进行ORDER BY” =>然后出于性能目的,我在外部查询上设置了相同的条件。 order by
我也必须在外部查询中再次使用,否则结果将默认排序。
现在有一个实际的性能问题,因为我大约有6k projects
,并且在没有任何条件的情况下运行此查询时,它需要大约15s:/当我通过指定条件来缩小结果范围时,时间将急剧下降。我发现某个地方为每个外部查询行结果都运行了子查询,当您在执行时观看时可能是真的:/
请问我如何优化查询?我在sql上工作不多,所以也许我从一开始就从错误的角度做了?
P.S。我已经尝试了WHERE projects.id IN(从项目中选择project.id ...),这丢弃了性能问题,但也丢弃了GROUP BY之前的ORDER BY
编辑。
我想检索projects
的列表,但我也想对其进行过滤和排序,最后我要获得patterns.id唯一(这就是为什么使用group by的原因)。
内部查询(p)中的order by没有意义(任何内部排序只会 具有任意效果)。
@Solarflare不幸的是。 group by将从分组结果中获取第一行。它保留加入的顺序。好吧,我相信它特定于MySql。此外,为了保持子查询的顺序,我可以在外部查询中使用ORDER BY NULL
:-)
还选择项目。* ...按pattern.id分组。(尽管与其他所有dbms相比,MySQL还是可以做到这一点)
因此我们可以假设我仅从文档中检索projects.id
,
MySQL扩展了GROUP BY的使用,以允许选择GROUP BY子句中未提及的字段