有谁能在这个笨拙的MySQL查询变得更糟之前帮我驯服它吗?

有谁能在这个笨拙的MySQL查询变得更糟之前帮我驯服它吗?,sql,mysql,Sql,Mysql,我不太擅长SQL,但我确实在学习 所以这篇文章提供了wordpress帖子下面几个列表的内容。一个是“来自该用户的更受欢迎的文章”,另一个是“该类别中更受欢迎的文章” 文章可以由编辑发布,也可以由登录或匿名用户提交。 它只是检查所有的文章,看看它们是否来自同一个用户,或者与显示列表的帖子属于同一个类别。当用户提交一篇文章时,它仍然是由发布文章的管理员“发布”的(因为他们必须首先获得批准)。因此,当用户提交一篇文章时,会出现一个单独的db条目 基本结构: select post_id, post_

我不太擅长SQL,但我确实在学习

所以这篇文章提供了wordpress帖子下面几个列表的内容。一个是“来自该用户的更受欢迎的文章”,另一个是“该类别中更受欢迎的文章”

文章可以由编辑发布,也可以由登录或匿名用户提交。 它只是检查所有的文章,看看它们是否来自同一个用户,或者与显示列表的帖子属于同一个类别。当用户提交一篇文章时,它仍然是由发布文章的管理员“发布”的(因为他们必须首先获得批准)。因此,当用户提交一篇文章时,会出现一个单独的db条目

基本结构:

select post_id, post_title, post_name, (
    //number of times this article has been
    //favorited, to help sort them
) as favorited, (
    //whether this article is from the same user
    select count(*) > 0 from wp_users //have to put something, it's just a flag
    where exists (
        //see if this post was authored by the the same user(s)
        and not exists (
            //make sure it's not a user submitted article. If it is,
            //we want to group it by the submitting user, not the
            //approving editor
        )
    )
    or exists (
        //see if an 'original submitter username' exists for this post,
        //and if so, see if it matches the post we're generating the list for
    )
) as under_users, (
    //see if this post is under the same category
) as under_category
还有我的疑问:

select p.ID, p.post_title, p.post_name, (
  select count(*)
  from wp_usermeta as um
  where um.meta_key = 'wpfp_favorites'
  and POSITION(CONCAT("\"",p.ID,"\"") IN um.meta_value)
) as favorited, (
  select count(*) > 0 from wp_users
  where exists ( 
    select *
    from wp_terms as t, wp_term_taxonomy as tt, wp_term_relationships as tr
    where tt.taxonomy = 'author'
    and tr.object_id = p.ID
    and tr.term_taxonomy_id = tt.term_taxonomy_id
    and t.term_id = tt.term_id
    and t.term_id in (
      select t2.term_id
      from wp_terms as t2, wp_term_taxonomy as tt2, wp_term_relationships as tr2
      where tt2.taxonomy = 'author'
      and tr2.object_id = 535
      and tr2.term_taxonomy_id = tt2.term_taxonomy_id
      and t2.term_id = tt2.term_id
    )
    and not exists (
      select *
      from wp_postmeta as pm
      where pm.post_id = 535
      and pm.meta_key = 'Original Submitter Username'
    )
  )
  or exists (
    select *
    from wp_postmeta as pm
    where pm.post_id = p.ID
    and pm.meta_key = 'Original Submitter Username'
    and pm.meta_value = (
      select pm2.meta_value
      from wp_postmeta as pm2
      where pm2.post_id = 535
      and pm2.meta_key = 'Original Submitter Username'
    )
  )  
) as under_users, (
  select count(*) > 0 from wp_users
  where exists (
    select *
    from wp_terms as t, wp_term_taxonomy as tt, wp_term_relationships as tr
    where tt.taxonomy = 'category'
    and tr.object_id = p.ID
    and tr.term_taxonomy_id = tt.term_taxonomy_id
    and t.term_id = tt.term_id
    and t.term_id in (
      select t2.term_id
      from wp_terms as t2, wp_term_taxonomy as tt2, wp_term_relationships as tr2
      where tt2.taxonomy = 'category'
      and tr2.object_id = 535
      and tr2.term_taxonomy_id = tt2.term_taxonomy_id
      and t2.term_id = tt2.term_id
      and t2.term_id not in (3, 4)
    )
  )
) as under_category
from wp_posts as p
where p.post_type = 'post' 
and p.ID != 535
and p.post_status = 'publish'
having (
  under_users != 0
  or under_category != 0
)
order by favorited desc
我觉得它可以短得多,好得多,但我不知道怎么做。我似乎在查询中多次查询相同的内容,我害怕添加任何其他内容(区分登录者和非提交者,按视图以及收藏夹对文章进行排序等),以免它自己崩溃并成为黑洞


有什么建议可以帮助我吗?

您最好在应用程序级别分离这些子查询。然后,您可以将
EXISTS
子句更改为
EXISTS IN(id…


我发现MySQL中的嵌套子查询往往非常慢,因为需要同时检查的行数太多。在应用程序级别中断子查询允许您使用缓存,并使您能够更好地控制子查询的操作,同时使SQL更易于阅读

您最好在应用程序级别分离这些子查询。然后,您可以将
EXISTS
子句更改为
EXISTS IN(id…


我发现MySQL中的嵌套子查询往往非常慢,因为需要同时检查的行数太多。在应用程序级别中断子查询允许您使用缓存,并使您能够更好地控制子查询的操作,同时使SQL更易于阅读

不要太担心您的查询太复杂。在现实世界的应用程序中,查询是这样的。如果开始出现问题(请记住,可以在SQL语句中嵌入注释),可以创建处理某些子查询的视图。例如,您对under_类别的子查询。您可以创建一个视图,这样

create view under_category_view as
    select tr.object_id AS p_id
        from wp_terms              as t,
             wp_term_taxonomy      as tt,
             wp_term_relationships as tr
        where tt.taxonomy             = 'category'
              and tr.term_taxonomy_id = tt.term_taxonomy_id
              and t.term_id           = tt.term_id
              and t.term_id in (select t2.term_id
                                    from wp_terms              as t2,
                                         wp_term_taxonomy      as tt2,
                                         wp_term_relationships as tr2
                                    where tt2.taxonomy = 'category'
                                          and tr2.object_id = 535
                                          and tr2.term_taxonomy_id = tt2.term_taxonomy_id
                                          and t2.term_id = tt2.term_id
                                          and t2.term_id not in (3, 4));
然后在你的大查询中你会使用

select count(*) > 0 from wp_users
  where exists (select *
                    from user_category_view
                    where p_id = p.id) as under_category

顺便说一句,我发现垂直拆分行和使用大缩进(正如我在这里所做的)有助于使粗块查询更易于阅读。

不要太担心查询的复杂性。在现实世界的应用程序中,查询是这样的。如果开始出现问题(请记住,可以在SQL语句中嵌入注释),可以创建处理某些子查询的视图。例如,您对under_类别的子查询。您可以创建一个视图,这样

create view under_category_view as
    select tr.object_id AS p_id
        from wp_terms              as t,
             wp_term_taxonomy      as tt,
             wp_term_relationships as tr
        where tt.taxonomy             = 'category'
              and tr.term_taxonomy_id = tt.term_taxonomy_id
              and t.term_id           = tt.term_id
              and t.term_id in (select t2.term_id
                                    from wp_terms              as t2,
                                         wp_term_taxonomy      as tt2,
                                         wp_term_relationships as tr2
                                    where tt2.taxonomy = 'category'
                                          and tr2.object_id = 535
                                          and tr2.term_taxonomy_id = tt2.term_taxonomy_id
                                          and t2.term_id = tt2.term_id
                                          and t2.term_id not in (3, 4));
然后在你的大查询中你会使用

select count(*) > 0 from wp_users
  where exists (select *
                    from user_category_view
                    where p_id = p.id) as under_category

顺便说一句,我发现垂直拆分行并使用大缩进(正如我在这里所做的)有助于使粗块查询更易于阅读。

除了检查是否至少有一行之外,您是否使用wp_用户?您似乎没有使用它的任何字段。它在那里的目的是什么?也许我就是看不出你在哪里使用它……我想把
select 1放在存在的地方(…
但它不允许我,我必须从某些东西中选择一些东西。这就是我使用它的全部目的。除了检查它是否至少有一行之外,你是否使用wp_用户?你似乎没有使用它的任何字段。它存在的目的是什么?也许我就是看不出你在哪里使用它…我想把
选择1放在存在的地方s(…
但它不允许我,我必须从某些东西中选择一些东西。这就是我使用它的全部目的。而且,在2个月后,当你回来修复一个bug时,你不会在看到这个庞大的查询后的几秒钟内变成一个疯狂的疯子。我不太清楚你的意思。我如何在不查询的情况下获得ID?我是否必须保留一个ID列表每当添加帖子时,at是否会被修改?@Carson,您将在应用程序级别的一个单独查询中获得ID。获得ID后,您将把它们格式化为逗号分隔的列表(小心删除后面的逗号),并以这种方式构建sql。这可能会有所帮助,我可以在应用程序中对ID进行分类,尽管由于帖子和用户之间的关系,获取每个ID所需的信息可能同样复杂。而且,在2个月后,当你回来修复一个bug时,你不会在看到那个庞大的查询后几秒钟变成一个疯狂的疯子。我不太清楚你的意思。我如何在不查询ID的情况下获取ID?我是否必须保留一个ID列表,以便在添加帖子时进行修改?@Carson,你可以在应用程序级别的单独查询中获取ID。一旦获取ID,你就可以将其格式化为逗号分隔的列表(小心地拆下尾部逗号),并以这种方式构建sql。这可能会有所帮助,我可以在应用程序中对ID进行排序,尽管由于帖子和用户之间的所有关系,获取每个ID所需的信息可能同样复杂。啊,视图。考虑到我需要使用仅当用户不存在于数据库的另一部分时,才从数据库中的一个位置选择该用户?我还需要进一步了解它,但我没有真正考虑将其部分存储在数据库中。谢谢:)啊,视图。我想我也可以使用一个存储过程来处理_users子查询下的
?考虑到我需要从数据库中的一个位置选择用户,如果它不存在于另一个部分中?我必须读一读它