帮我优化这个查询

时间:2011-09-26 15:01:16

标签: mysql database optimization query-optimization subquery

我有一个我正在设计的应用程序的查询。有一个引用表,一个authors表和一个reference_authors表。有一个子查询返回给定引用的所有作者,然后我在php中显示格式。子查询和查询单独运行既美观又快速。但是,只要将子查询放入主查询中,整个过程就需要超过120秒才能运行。我会在这一个上留下一些新鲜的眼睛。 感谢。

SELECT
rf.reference_id,
rf.reference_type_id,
rf.article_title,
rf.publication,
rf.annotation,
rf.publication_year,
(SELECT GROUP_CONCAT(a.author_name)
FROM authors_final AS a
INNER JOIN reference_authors AS ra2 ON ra2.author_id = a.author_id
WHERE ra2.reference_id = rf.reference_id
GROUP BY ra2.reference_id) AS authors
FROM
references_final AS rf
INNER JOIN reference_authors AS ra ON rf.reference_id = ra.reference_id
LEFT JOIN reference_institutes AS ri ON rf.reference_id = ri.reference_id;

这是固定查询。谢谢大家的建议。

SELECT
rf.reference_id,
rf.reference_type_id,
rf.article_title,
rf.publication,
rf.annotation,
rf.publication_year,
GROUP_CONCAT(a.author_name) AS authors
FROM
references_final as rf
INNER JOIN (reference_authors AS ra INNER JOIN authors_final AS a ON ra.author_id = a.author_id)
ON rf.reference_id = ra.reference_id
LEFT JOIN reference_institutes AS ri ON rf.reference_id = ri.reference_id
GROUP BY rf.reference_id

2 个答案:

答案 0 :(得分:0)

你说子查询在隔离方面很好而且速度很快,但它现在显然在每一行中运行--100行= 100个子查询。

假设您的所有外键上的索引与子查询一样好。

一个选项是离开连接作者并创建一个笛卡尔积 - 你将返回更多的行,并且需要一些代码来获得相同的最终结果,但它会减少对数据库的压力,并且会更快地运行

如果您已经进行了分页并且说要返回10行,那么单独调用10个单独的调用也会非常快。

答案 1 :(得分:0)

虽然不是每个子查询都可以重写为内连接,但我认为你的子查询可以。

从120秒到78毫秒并不是一个糟糕的改进 - 大约三个数量级。休息一天。

明天回来时,请开始在源代码中查找其他子查询。