2017-08-11 24 views
1

私は現在クエリを書いています。 投稿内のユーザー、投稿、追加情報テーブルから情報を取得します(post_views_info)。mysql:同じテーブルで3回クエリ

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 

上記のクエリでは、同じテーブルを3回クエリして、ポストの数「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 

同じテーブルを3回クエリする方が良いと思います。 どのコードがパフォーマンス面で優れていますか?

ありがとうございました。

答えて

1

第2の選択肢は、パフォーマンス面でより効果的だと思います。ここでは実行するクエリの数が少なくなるためです。

また、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 
関連する問題