[英]How can I optimize this VERY slow MySQL query?
我有一个基于WordPress的网站,该网站为区域科学期刊的学术文章进行了分类。
简而言之,该系统有数千个“职位”,并且每个职位都有一个“ pub_type”分类法,其中仅选择了1个术语:“手稿”或其他。
每个帖子还具有与其相关的各种其他分类法/术语。
目标:获取特定分类法的术语列表。 对于每个术语,计算与其相关的帖子数,并确定在“ pub_type”分类法中设置了“ Manuscript”的帖子数量。
当前查询:
SELECT term_id, term_id as term_id_b, name, slug,
( SELECT COUNT(id) FROM wp_posts WHERE id IN
( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN
( SELECT term_taxonomy_id FROM wp_term_taxonomy WHERE term_id = term_id_b )
) AND post_status = "publish" ) as count,
( SELECT COUNT(id) FROM wp_posts WHERE id IN
( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN
( SELECT term_taxonomy_id FROM wp_term_taxonomy WHERE term_id IN
( SELECT term_id FROM wp_terms WHERE term_id = term_id_b )
)
)
AND id IN
( SELECT object_id FROM wp_term_relationships WHERE term_taxonomy_id IN
( SELECT term_taxonomy_id FROM wp_term_taxonomy WHERE term_id =
( SELECT term_id FROM wp_terms WHERE name = "Manuscript" )
AND taxonomy = "pub_type" )
)
AND post_status = "publish"
) as manuscript_count
FROM wp_terms
WHERE term_id IN
( SELECT term_id FROM wp_term_taxonomy WHERE taxonomy = "'.$taxonomy.'" )
ORDER BY name ASC
尽管此查询确实有效 ,但运行速度非常慢...在3-5分钟之间,具体取决于服务器负载。 太糟糕了,为了保持网站性能,我不得不将查询结果缓存到JSON文本文件中,并且仅让查询每2小时运行一次。
我知道这里的主要问题是我对所有内容都使用了子查询。 当我尝试了解有关使用联接的更多信息时,我还不了解以其他任何方式编写此查询。
有人可以提供一些有关如何驯服这种野兽的见解或建议吗?
编辑:这是查询的EXPLAIN输出的屏幕截图:
有关IN
的使用以及它如何对查询速度产生负面影响,请参见这篇出色的文章 。 这已经把您的问题写满了。
本质上,使用传统的IN(values)
查询,您只是在搜索每个值。 在子查询IN
,您可以使用( IN(SELECT)
)。
在其中,作者引用了MySQL的手册:
如果内部查询和外部查询分别返回M和N行,则执行时间将变成O(MxN)的顺序,而不是像不相关子查询那样的O(M + N)。
使用此逻辑,您可以将wp_posts
作为外部查询,在其中将wp_terms_relationship
嵌套在10行中,并在其中再次嵌套wp_terms
。 那是949*(10*1))
。 第二次,您只有两个级别的嵌套,但是由于最终级别只有一行,因此它仍然具有相同的影响:您最终将解析9490行。
子查询不是您的朋友。 尽管有时可能有必要,但几乎可以始终使用JOIN
解决它们。 根据您的目标,这似乎没有太大不同。 通过重写此查询和伸展尝试使用JOIN...ON
,你会发现,一个简短的学习曲线之后会更容易阅读自己的代码,请按照其逻辑的进展,以及最有可能的,看到它加快太。 至少,请尽可能利用join
。 稍后您将感谢您。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.