0

そのため、SQLクエリを最適化する過程にあります。私はそれをかなりきれいにしましたが、まだやるべきことがいくつかあります。以下のクエリを参照してください。

コンペティションtbl:ID、fb_share_points、tw_share_points

comp_mapper tbl:id、referrer_user_id、user_subscription_id、has_fb_shared、has_tw_shared、competition_id

SELECT 
    IF (cm.has_fb_shared = 1, IFNULL(c.fb_share_points,0), 0) 
    + IF (cm.has_tw_shared = 1, IFNULL(c.tw_share_points,0), 0) 
    + (SELECT count(*) FROM comp_mapper as cm2
        WHERE cm2.comp_id = cm.comp_id 
        AND cm2.referrer_user_id = us.user_id)
    as shares
FROM competitions AS c
JOIN comp_mapper as cm ON cm.competition_id = c.id
JOIN user_subscription as us on cm.user_subscription_id = us.id
WHERE c.id = :id
ORDER BY shares DESC
LIMIT :limit

ユーザーが紹介されると、紹介するユーザーのIDがコンテスト参加者のreferrer_user_id列に配置されます。サブクエリは、他のユーザーを紹介したコンテスト参加者の数を計算します。クエリ自体の実行にはかなりの時間がかかるため、現在、サブクエリなしでこれを記述する別の方法を見つけようとしています。誰かが提案や推奨事項を持っているなら、共有してください!

4

1 に答える 1

1

これは同等の結果を返すはずです。ここでの違いは、相関サブクエリではなく、エイリアスが付けられたインラインビュー(MySQLでは派生テーブルrfと呼ばれます)があることです。

SELECT IF(cm.has_fb_shared = 1, IFNULL(c.fb_share_points,0), 0) 
     + IF(cm.has_tw_shared = 1, IFNULL(c.tw_share_points,0), 0) 
     + IFNULL(rf.ref_count,0) AS shares
  FROM competitions c
  JOIN comp_mapper cm 
    ON cm.competition_id = c.id
  JOIN user_subscription us
    ON us.id = cm.user_subscription_id
  LEFT
  JOIN (  
         SELECT cm2.referrer_user_id 
              , COUNT(1) AS ref_count
           FROM comp_mapper cm2
          WHERE cm2.comp_id = :id
          GROUP BY cm2.referrer_user_id
       ) rf
    ON rf.referrer_user_id = us.user_id
 WHERE c.id = :id
 ORDER BY shares DESC
 LIMIT :limit

クエリが単一の列(shares)のみを含み、他の列を含まない行のセットを返すのは少し奇妙に思います。単一の値を返すことを目的としている場合はSUM()、選択リストに集計関数(つまり)が含まれている必要があります。

于 2012-12-19T03:14:53.633 に答える