2010-04-25 3 views
1

LEFT JOIN 문을보다 간단한 쿼리에 결합하는 방법이 있다는 것을 기억하는 것 같습니다. 나는 다음의 질의를 가지고 누군가가 친절하게 그것을 볼 수 있기를 희망했다. 당신은 그냥 가입 유지하기 위해 앞서 언급 한 열을 참조 할 수 있습니다)mysql에서 조인을 결합하는 구문

SET @userId = 8; 

SELECT ug.user_id, COUNT(DISTINCT goal_id) as matches 
FROM user_goal ug, user u, profile p 
LEFT JOIN user_block ub ON @userId = ub.blocked_id 
LEFT JOIN user_block ub2 ON @userId = ub2.blocker_id 
LEFT JOIN user_user uu ON @userId = uu.user_id 
LEFT JOIN friend_request fr ON @userId = fr.user_id 
WHERE ug.user_id = u.id AND u.profile_id = p.id 
AND (ub.blocker_id IS NULL OR ub.blocker_id != ug.user_id) 
AND (ub2.blocked_id IS NULL OR ub2.blocked_id != ug.user_id) 
AND (uu.user_friends_id IS NULL OR uu.user_friends_id != ug.user_id) 
AND (fr.to_user_id IS NULL OR (fr.to_user_id != ug.user_id)) 
AND [email protected] 
AND p.suggestible 
AND goal_id IN (SELECT iug.goal_id FROM user_goal iug WHERE [email protected]) 
GROUP BY user_id ORDER BY matches DESC LIMIT 4 

답변

3

당신은 @userId로 시작하는 것을 제거하여이 전체 쿼리를 향상시킬 수 있습니다.

그러면 하위 쿼리에 문제가 발생할 수 있습니다. 거기에있을 필요는 없습니다. 이 하위 쿼리는 여기에서 느린 쿼리 실행을 유발할 것입니다. 하위 쿼리를 합류하려는 파생 테이블에 통합 할 수 있습니다 (동일한 user_id을 사용하기 때문에). 결과 집합의 각 레코드에 대해 한 번만 실행되는 것이 아니라 한 번 실행됩니다.

SELECT 
    ug.user_id, 
    COUNT(DISTINCT goal_id) as matches 
FROM 
    user_goal ug 
    INNER JOIN user u ON ug.user_id = u.id 
    INNER JOIN profile p ON u.profile_id = p.id 
    LEFT JOIN user_block ub ON u.id = ub.blocked_id 
    LEFT JOIN user_block ub2 ON u.id = ub2.blocker_id 
    LEFT JOIN user_user uu ON u.id = uu.user_id 
    LEFT JOIN friend_request fr ON u.id = fr.user_id 
    LEFT JOIN (
    SELECT iug.goal_id FROM user_goal 
) iug ON iug.user_id = u.id 
WHERE 
    /* I looked at your WHERE clause for a while and couldn't get my head 
    around what you're trying to do so I'll leave this to you */ 

직접적으로 하위 쿼리를 퍼팅 가입 정말 일을 속도 (및 이럴 물건을 정리하는)은 파생 테이블을 생성 이름.

관련 문제