任何人都可以帮助我在恶化之前驯服这个笨拙的MySQL查询吗?

时间:2010-08-13 22:23:50

标签: sql mysql

我不擅长SQL,但我当然在学习。

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

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

基本结构:

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

我觉得它可能会更短,更好,但我不知道该怎么做。我似乎在查询中多次查询同样的事情,我害怕添加任何其他东西(区分登录和匿名提交者,按视图和收藏夹排序文章等)以免崩溃在其本身,成为一个黑洞。

有任何提示可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

您可能最好在应用程序级别拆分其中一些子查询。然后,您可以将EXISTS条款更改为EXISTS IN (ids...)

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

答案 1 :(得分:1)

不要过分担心您的查询是否复杂。在实际应用程序中,查询会像这样。如果它开始成为一个问题(记住你可以在SQL语句中嵌入注释),你可以创建视图来处理一些子查询。例如,under_category的子查询。你可以创建一个视图......

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

顺便说一句,我发现垂直分割线并使用大缩进,因为我在这里做了有助于使粗略查询更容易阅读。