如何优化这个非常慢的MySQL查询?

如何优化这个非常慢的MySQL查询?,mysql,wordpress,performance,subquery,taxonomy,Mysql,Wordpress,Performance,Subquery,Taxonomy,我有一个基于WordPress的网站,为一家地区性科学杂志编目学术文章 简单地说,这个系统有几千篇文章,每一篇都有一个pub_类型的分类法,其中只选择了一个术语:手稿或其他 每一篇文章都有与之相关的各种其他分类法/术语 目标:获取特定分类法的术语列表。对于每个术语,计算与之相关的帖子数量,并确定其中有多少帖子在pub_类型分类法中设置了手稿 当前查询: 虽然此查询确实有效,但运行速度非常慢。。。在3-5分钟之间,具体取决于服务器负载。这太糟糕了,为了保持站点性能,我不得不将查询结果缓存到JSON

我有一个基于WordPress的网站,为一家地区性科学杂志编目学术文章

简单地说,这个系统有几千篇文章,每一篇都有一个pub_类型的分类法,其中只选择了一个术语:手稿或其他

每一篇文章都有与之相关的各种其他分类法/术语

目标:获取特定分类法的术语列表。对于每个术语,计算与之相关的帖子数量,并确定其中有多少帖子在pub_类型分类法中设置了手稿

当前查询:

虽然此查询确实有效,但运行速度非常慢。。。在3-5分钟之间,具体取决于服务器负载。这太糟糕了,为了保持站点性能,我不得不将查询结果缓存到JSON文本文件中,并且只让查询每2小时运行一次

我知道这里的主要问题是我对所有事情都使用了子查询。当我试图学习更多关于使用联接的知识时,我还不知道如何以其他方式编写此查询

有人能给我一些关于如何驯服这头野兽的见解或建议吗

编辑:以下是查询解释输出的屏幕截图:

请参阅IN的使用以及它如何对查询速度产生负面影响。这上面写满了你的问题

本质上,使用传统的INvalues查询,您只需搜索每个值。在子查询中,按INSELECT

在其中,作者引用了MySQL的手册:

如果内部查询和外部查询分别返回M行和N行,则执行时间的顺序为OMxN,而不是与不相关子查询相同的OM+N

使用此逻辑,您可以将处的wp_posts作为外部查询,并在其中嵌套10行的wp_terms_关系,然后在该嵌套中再次嵌套wp_terms。那个是949*10*1。第二次,您只有两个嵌套级别,但由于最后一个级别只有一行,因此影响仍然相同:您将解析9490行


子查询不是您的朋友。虽然有时它们可能是必需的,但几乎总是可以使用JOIN来解决。这似乎与你的目标没有太大区别。通过重写此查询并尝试使用JOIN…ON,您会发现在经过一个简短的学习过程后,阅读自己的代码、遵循其逻辑进程将变得更加容易,而且很可能还会看到它的速度加快。至少,尽可能利用连接。稍后您将感谢您自己。

很多时间用于子查询,WHERE EXISTS比WHERE IN快。但是,为了给您一个更好的答案,我需要查看查询计划。你能在你的问题中添加解释计划输出吗?如果我想去那里,我不会从这里开始考虑提供适当的DDL和/或SqLFIDLE连同期望的结果集。你是说你想这样做:计算PUBY类型分类的每个术语的帖子数量?
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