Php 在MYSQL中将复杂查询分解为临时表
我正在为学术书籍开发个人项目。我有一些表格,每个表格有+30000行,用于作品、版本、作者等。书籍的所有信息——体裁、主题、作者、出版商等——都分布在许多具有不同类型关系的表格中 我有一个对主页的有效查询,但该网站需要六秒钟才能加载。很多时候…我想知道哪种方法是获取临时表所需的所有数据的正确方法 我现在要做的是将临时表_work与另一个表的相关数据连接起来,比如«genre»。但是«work»和«genre»之间的关系是通过临时表«work_has_genre»完成的。我知道如何在一个查询中使用普通表:Php 在MYSQL中将复杂查询分解为临时表,php,mysql,Php,Mysql,我正在为学术书籍开发个人项目。我有一些表格,每个表格有+30000行,用于作品、版本、作者等。书籍的所有信息——体裁、主题、作者、出版商等——都分布在许多具有不同类型关系的表格中 我有一个对主页的有效查询,但该网站需要六秒钟才能加载。很多时候…我想知道哪种方法是获取临时表所需的所有数据的正确方法 我现在要做的是将临时表_work与另一个表的相关数据连接起来,比如«genre»。但是«work»和«genre»之间的关系是通过临时表«work_has_genre»完成的。我知道如何在一个查询中使用
SELECT *
FROM work a
LEFT JOIN (
SELECT GROUP_CONCAT(f_a.id SEPARATOR '|') AS genre_id, GROUP_CONCAT(f_a.genre SEPARATOR '|') AS genre_name, f_b.work_id AS _work_id
FROM genre f_a
INNER JOIN (
SELECT *
FROM work_has_genre f_b_a
) f_b
ON f_a.id=f_b.genre_id
GROUP BY f_b.work_id
) f
ON a.id=f._work_id
WHERE a.id=13
我想我们的想法应该是把这些行动分成几个部分,但我不知道怎么做。有人能帮我写点伪代码吗?或许这不是最好的方法。任何想法都将受到欢迎
A.正如我在评论中所说的,我首先建议尽可能多地重新处理/展平子查询,但一旦您使用了半独立聚合,临时表可能会有所帮助
通常,模式是将每个这样的聚合子查询的结果放入它自己的临时表(在子查询与主查询联接的字段上有一个索引),即使这意味着将表(以及主查询的位置)添加到原始子查询,然后在主查询中联接到临时表。正如我在评论中所说,首先,我建议首先尽可能多地重新处理/展平子查询,但一旦您使用了半独立聚合,临时表可能会有所帮助
通常,模式是将每个这样的聚合子查询的结果放入它自己的临时表中(在子查询与主查询联接的字段上有一个索引),即使这意味着向原始子查询添加表(以及主查询的WHERE),然后连接到主查询中的临时表。第一个想法:可以去掉不必要的子查询(有些可能是,但有些显然不是)。示例:
c
和d
中的聚合可能要求它们是子查询,但并不要求它们拥有自己的子查询。你说得对,我可以多次清理该查询……直到现在我才意识到这一点。但是它仍然会很慢,如果我能把它分成几个部分,那就太好了。当您简化子查询时,您可能会发现您可以将一些完全合并到主查询中,并通过仔细使用COUNT(DISTINCT…
,GROUP\u CONCAT)减少对某些表的重复引用(例如work\u has\u edition
)(不同的…)
,等等。当然,这并不能保证你会在速度方面得到很大的提高;根据你的数据结构,它甚至可能会有更差的性能。是的,有这么多数据,子查询的改进非常小。这就是为什么我想用不同的方法处理临时表的原因……30000行不是很多dataFirst Thinks:您可以摆脱不必要的子查询(有些可能是,但有些显然不是).示例:c
和d
中的聚合可能要求它们是子查询,但不要求它们有自己的子查询。你是有道理的,我可以多次清理该查询…直到现在我才意识到。但它仍然会很慢,如果我可以将其分解为多个部分,那就太好了。当你简化在ubqueries中,您可能会发现可以将一些完全合并到主查询中,并通过仔细使用COUNT(DISTINCT…
,GROUP\u CONCAT(DISTINCT…)减少对某些表的重复引用(例如work\u has\u edition
)
,等等。当然,这并不能保证你会在速度方面得到很大的提高;根据你的数据结构,它甚至可能会有更差的性能。是的,有这么多数据,子查询的改进非常小。这就是为什么我想用不同的方法处理临时表的原因……30000行不是很多dataSo的方法是:首先,将我的查询展平;然后,将其分成几个部分,并将它们放入不同的临时表中。然后在最后连接临时表以输出所有数据。是否正确?是的。每个子查询通常可以执行得更快,然后将其结果存储在索引临时表中,以便在最后的q中快速连接当然,直接表连接几乎总是比子查询(或者先将单独查询的结果放入临时表)快,但有时这是不可能的(例如使用这种聚合混合)。谢谢你的解释!事实上,我正在展平主查询,并且我可以制作主选择中的几乎所有concat。但无论如何,展平后,我会将其拆分为临时表。因此,方法是首先展平我的查询;然后,将其拆分为多个部分并放入不同的临时表中。然后加入临时表在最后创建表以输出所有数据。是否正确?是的。每个子查询通常可以执行得更快,然后将其结果存储在索引临时表中,以便在最终查询中快速联接。当然,直接表联接几乎总是比子查询快(或者先将单独查询的结果放入临时表中),但有时这是不可能的(例如使用这种聚合混合)。感谢您的解释!事实上,我正在展平主查询,并且我可以在主选择中生成几乎所有的concat。但无论如何,展平后,我将在临时表中分解它。