2012-10-27 5 views
1

많은 테이블과 왼쪽 조인이 포함 된 MySQL 상황이 있는데 문제가 있습니다.다중 테이블에서 왼쪽 조인 문제 해결

나는 그것을 단계적으로 간소화하려고 노력할 것이다.

내가 수행하려고하는 주요 작업은 두 개의 테이블을 결합하는 것입니다. 첫 번째 테이블에는 항목이 포함되고 두 번째 테이블에는 항목에 대해 수행 된 작업이 포함됩니다.

select item.ID, count(action.ID) as cnt 
from item 
left join action on action.itemID=item.ID 
group by ID 

다음 단계는 실제로 특정 유형의 계산 필요가있다 : 나는 솔루션으로 (어떤 행동이 그들에 수행하지 않은 경우에도) 그래서 왼쪽 가입 출력 할 항목 테이블의 모든 행을 보인다 필요 항목 중. 다른 유형은 필요 없기 때문에 where 절로 필터링합니다.

select item.ID, count(action.ID) as cnt 
from item 
left join action on action.itemID=item.ID 
where item.type=3 
group by ID 

이제는 상황이 좀 복잡해집니다. 다른 테이블 (정보)을 사용하여 일부 항목을 필터링해야합니다. 거기, 나는 그것을 어떻게하는지 잘 몰랐다. 그러나 간단한 조인과 where 절이이를 수행했습니다.

select item.ID, count(action.ID) as cnt 
from (item, info) 
left join action on action.itemID=item.ID 
where item.type=3 and info.itemID=itemID and info.fr is not null 
group by ID 

지금까지는 그렇게 좋았습니다. 내 쿼리가 작동하고 예상대로 성능이 있습니다. 이제해야 할 마지막 작업은 다른 작업 (하위 작업)을 기반으로 일부 작업을 필터링 (제외)하는 것입니다. 이것은 일이 정말로 느리고 혼란을 일으키는 곳입니다. 나는이 시도 :이 시점에서

select item.ID, count(action.ID) as cnt 
from (item, info) 
left join (
      action join subaction on subaction.actionID=action.ID and subaction.type=6 
     ) on action.itemID=item.ID 
where item.type=3 and info.itemID=itemID and info.fr is not null 
group by ID 

를 쿼리가 suddently 1000 개 이상의 배 속도가 느려집니다. 나는 분명히 뭔가 잘못하고있다!

나는 거의 필요한 것을 수행하는 간단한 쿼리를 시도했다. 유일한 문제는 일치하는 작업을 수행해야하는 항목이 포함되어 있지 않다는 것입니다. 그러나 나는 그들도 필요하다.

select item.ID, count(action.ID) as cnt 
from item, info, action, subaction 
where item.type=3 and info.itemID=itemID and info.fr is not null and 
     action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6 
group by ID 

누구나 이러한 문제를 해결하는 방법에 대한 제안이 있습니까? 표준 방법이 있습니까? 고마워요!

편집

사실, 내가 제출 한 마지막 쿼리 내가 필요한 거의 : 그것은 하위 쿼리를 포함하지 않는, 정말 성능이 좋은 것입니다, 내 인덱스의 최적 사용을 만들고, 읽기 쉬운 등

select item.ID, count(action.ID) as cnt 
from item, info, action, subaction 
where item.type=3 and info.itemID=itemID and info.fr is not null and 
     action.itemID=item.ID subaction.actionID=action.ID and subaction.type=6 
group by ID 

카운트 (action.ID가) 그래서 내 질문은 정말 약간 위를 어떻게 수정해야 추측 0

을 때 그 item.ID를 포함하지 않는입니다 작동하지 않는 유일한 작은 것 큐 ry 또한 count (action.ID)가 0 일 때 item.IDs를 반환합니다. 내가 보는 것으로부터 이것은 퍼포먼스와 인덱스 사용을 변경해서는 안된다. 여분의 item.IDs를 0으로 계산하면됩니다. 시도는 다음과 같이 조인

+1

당신이 봤어은'쿼리를 EXPLAIN'ing? –

답변

1

(최초 가입하기 전에 필터 조건을 적용하려고) :

 SELECT item.ID, count(action.ID) as cnt 
     FROM item JOIN info 
      ON (item.type=3 AND info.fr is not null AND info.itemID=item.itemID) 
      LEFT JOIN action 
      ON (action.itemID=item.ID) 
      JOIN subaction 
      ON (subaction.actionID=action.ID and subaction.type=6) 
     GROUP by item.ID; 

편집 :

 SELECT item.ID, count(action.ID) as cnt 
     FROM item JOIN info 
      ON (item.type=3 AND info.fr is not null AND info.itemID=item.itemID) 
      LEFT JOIN 
      (select a.* FROM action 
       JOIN subaction 
       ON (subaction.actionID=action.ID and subaction.type=6)) AS act 
      ON (act.itemID=item.ID) 
     GROUP by item.ID; 
+0

그 문제는 마지막 JOIN이 동작이없는 느슨한 항목을 만드는 것입니다.즉, 마지막 JOIN은 LEFT JOIN의 효과를 취소합니다. –

+0

그리고 마지막으로 JOIN을 LEFT JOIN으로 만들면 올바른 결과를 얻을 수 있지만 실적은 크게 떨어집니다. –

+0

@GillesjrBisson 답변에 다른 쿼리가 추가되었습니다. 도움이 될지 알려주시겠습니까? –