2012-12-19 2 views
0

SQL 쿼리를 최적화하는 중입니다. 나는 그것을 상당히 청소했지만 여전히해야 할 일이있다. 아래를 참조 쿼리하위 쿼리를 사용하지 않고 쿼리를 다시 작성하십시오.

경기 TBL : ID, fb_share_points, tw_share_points

comp_mapper TBL : 아이디, referrer_user_id, user_subscription_id, has_fb_shared, has_tw_shared,

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 

을 competition_id 사용자가 언급 될 때, 추천 사용자의 ID는 경쟁 참가자의 referrer_user_id 열에 배치됩니다. 하위 쿼리는 경쟁 참여자 중 몇 명이 다른 사용자를 추천했는지 계산합니다. 나는 현재 쿼리를 실행하는 데 꽤 오랜 시간이 걸리기 때문에 서브 쿼리없이 다른 방법으로이 쿼리를 작성하려고한다. 누구든지 제안이나 권장 사항이 있다면 공유하십시오!

답변

1

이렇게하면 동일한 결과가 반환됩니다. 차이점은 상관 관계가있는 서브 쿼리가 아니라, 인라인 뷰 (파생 테이블)이며 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())가 있어야합니다.

+0

우수 답변, 정말 고마워요! 더 많은 열이 있었고, 나는 그 점을 지키기 위해 그들을 제외 시켰습니다. – Rijndael

관련 문제