2017-08-11 155 views
1

我正在寫一個查詢。 從帖子(post_views_info)中的用戶,帖子和其他信息表中檢索信息。mysql:在同一張表上查詢三次

SELECT 
    u.email, 
    u.user_nm, 
    p.pid, 
    p.post_ttl, 
    p.date, 
    p.ref_level, 
    p.ref_origin, 
    p.ref_step, 
    date(p.date) = date(now()) AS is_today, 
    (SELECT category_path FROM post_category WHERE category_id = p.category_id) as category_full_path, 
    (SELECT COUNT(*) FROM post_status_info AS sub_i WHERE sub_i.pid = p.pid AND sub_i.status = 'A') AS recommendCount, 
    (SELECT COUNT(*) FROM post_status_info AS sub_i WHERE sub_i.pid = p.pid AND sub_i.status = 'B') AS oppositeCount, 
    (SELECT COUNT(*) FROM post_status_info AS sub_i WHERE sub_i.pid = p.pid AND sub_i.status = 'C') AS reportCount 
FROM 
    (
     SELECT * 
     FROM post as p 
     WHERE 
      p.is_enable = 1 
     ORDER BY 
      p.ref_origin DESC, 
      p.ref_step ASC 
    ) as p, 
    user AS u 
WHERE 
    p.uid = u.uid 
ORDER BY 
    ref_origin DESC, 
    ref_step ASC 

在上面的查詢,我們查詢同桌三次獲得職位「A」,「B」,「C」的數量。

爲了解決這個問題,我改變了查詢如下。

SELECT 
    u.email, 
    u.user_nm, 
    p.pid, 
    p.post_ttl, 
    p.date, 
    p.ref_level, 
    p.ref_origin, 
    psi.reportCount, 
    psi.recommendCount, 
    psi.oppositeCount, 
    p.ref_step, 
    date(p.date) = date(now()) AS is_today, 
    (SELECT category_path FROM post_category WHERE category_id =  p.category_id) as category_full_path 
FROM 
    user AS u, 
    (
     SELECT * 
     FROM post as p 
     WHERE 
      p.is_enable = 1 
     ORDER BY 
      p.ref_origin DESC, 
      p.ref_step ASC 
     LIMIT 0, 15 
    ) as p left join 
    (
     SELECT 
       pid, 
       COUNT(if(status = 'A', 1, null)) AS reportCount, 
       COUNT(if(status = 'B', 1, null)) AS recommendCount, 
       COUNT(if(status = 'C', 1, null)) AS oppositeCount 
     FROM post_status_info 
     group by pid 
    ) AS psi 
on 
    psi.pid = p.pid 
WHERE 
    p.uid = u.uid 
ORDER BY 
    ref_origin DESC, 
    ref_step ASC 

我認爲最好是查詢同一張表三次。 哪些代碼在性能方面更好?

謝謝。

回答

1

我認爲第二個選項在性能方面更加卓有成效。因爲這裏我們有更少的查詢執行。

你也可以使用CASE來做到這一點。

SELECT 
u.email, 
u.user_nm, 
p.pid, 
p.post_ttl, 
p.date, 
p.ref_level, 
p.ref_origin, 
p.ref_step, 
date(p.date) = date(now()) AS is_today, 
(SELECT category_path FROM post_category WHERE category_id = p.category_id) as category_full_path, 
(SUM(CASE WHEN sub_i.status = 'A' THEN 1 ELSE 0 END)) AS recommendCount, 
(SUM(CASE WHEN sub_i.status = 'B' THEN 1 ELSE 0 END)) AS oppositeCount, 
(SUM(CASE WHEN sub_i.status = 'C' THEN 1 ELSE 0 END)) AS reportCount 
FROM 
(
    SELECT * 
    FROM post as p 
    WHERE 
     p.is_enable = 1 
    ORDER BY 
     p.ref_origin DESC, 
     p.ref_step ASC 
) as p, 
INNER JOIN user AS u ON u.uid = p.uid 
INNER JOIN post_status_info as sub_i ON p.pid = sub_i.pid 
GROUP BY p.pid 
ORDER BY 
ref_origin DESC, 
ref_step ASC