代码之家  ›  专栏  ›  技术社区  ›  cabrerahector

将联接查询重写为子查询,缺少行?

  •  0
  • cabrerahector  · 技术社区  · 6 年前

    我有以下返回这些行的MySQL查询:

    SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, SUM(v.pageviews) AS pageviews, IFNULL(c.comment_count, 0) AS comment_count 
    FROM `views` v 
    LEFT JOIN `posts` p ON v.postid = p.ID 
    LEFT JOIN (SELECT comment_post_ID, COUNT(comment_post_ID) AS comment_count FROM `comments` WHERE comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND comment_approved = 1 GROUP BY comment_post_ID) c ON p.ID = c.comment_post_ID 
    WHERE 1 = 1 AND p.post_type IN('post') AND v.view_datetime > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0;
    

    JOIN query

    我目前正在尝试使用子查询而不是联接来重写它,以检查性能是否更好。

    下面的查询返回相同的结果(除了 comment_count 列,因为我们只查询两个表而不是三个表):

    SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, v.pageviews AS pageviews 
    FROM `posts` p,
        (SELECT SUM(pageviews) AS pageviews, postid FROM `views` WHERE view_datetime > DATE_SUB( '2018-08-16 18:34:46', INTERVAL 29 DAY) GROUP BY postid) v
    WHERE 1 = 1 AND p.ID = v.postid AND p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0
    

    subqueries query

    但是,如果我加上 comments 表中,没有注释的帖子会被自动排除在外(比如ID) 2956 与原始查询相比,返回不同的结果:

    SELECT p.ID AS id, p.post_title AS title, p.post_author AS uid, v.pageviews AS pageviews, IFNULL(c.comment_count, 0) AS comment_count 
    FROM `posts` p,
        (SELECT SUM(pageviews) AS pageviews, postid FROM `views` WHERE view_datetime > DATE_SUB( '2018-08-16 18:34:46', INTERVAL 29 DAY) GROUP BY postid) v,
        (SELECT COUNT(comment_post_ID) AS comment_count, comment_post_ID FROM `comments` WHERE comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND comment_approved = 1 GROUP BY comment_post_ID) c 
    WHERE 1 = 1 AND p.ID = v.postid AND v.postid = c.comment_post_ID AND p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish' GROUP BY v.postid ORDER BY pageviews DESC LIMIT 5 OFFSET 0
    

    subqueries query with comments table

    我对这些东西还不是很有经验(你可以告诉我),所以任何帮助/提示来理解正在发生的事情都将非常感激。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Nick SamSmith1986    6 年前

    SELECT id, post_title AS title, post_author AS uid, 
        (SELECT SUM(pageviews) 
         FROM views v 
         WHERE v.postid = posts.id AND 
               v.view_datetime > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY)
        ) AS pageviews,
        (SELECT COUNT(comment_post_ID) 
         FROM comments c 
         WHERE c.comment_post_ID = posts.id AND
               c.comment_date_gmt > DATE_SUB('2018-08-16 18:34:46', INTERVAL 29 DAY) AND 
               c.comment_approved = 1
        ) AS comment_count
    FROM posts
    WHERE p.post_type IN('post') AND p.post_password = '' AND p.post_status = 'publish'
    ORDER BY pageviews DESC 
    LIMIT 5 OFFSET 0;