2011-03-08 4 views
0

개념적으로 필자는 시스템의 모든 사용자에 대해 8 개의 개별 설문 조사 점수를 얻으려고합니다. 동일한 행에 출력 된 주어진 사용자에게 연결된 8 개의 점수를 출력하고 싶습니다. 다음은이를 달성하기 위해 최선 샷 :MySQL Query Optimization은 불필요한 조인을 제거합니다.

SELECT cp.CONSUMER_ID, 
     bsr1.SCORE AS SET_1_SCORE, 
     bsr2.SCORE AS SET_2_SCORE, 
     bsr3.SCORE AS SET_3_SCORE, 
     bsr4.SCORE AS SET_4_SCORE, 
     bsr5.SCORE AS SET_5_SCORE, 
     bsr6.SCORE AS SET_6_SCORE, 
     bsr7.SCORE AS SET_7_SCORE, 
     bsr8.SCORE AS SET_8_SCORE 
FROM 
CONSUMER_PROFILE AS cp 
LEFT JOIN survey_scores AS bsr1 
ON bsr1.SET_ORDER=1 
AND bsr1.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr2 
ON bsr2.SET_ORDER=2 
AND bsr2.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr3 
ON bsr3.SET_ORDER=3 
AND bsr3.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr4 
ON bsr4.SET_ORDER=4 
AND bsr4.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr5 
ON bsr5.SET_ORDER=5 
AND bsr5.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr6 
ON bsr6.SET_ORDER=6 
AND bsr6.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr7 
ON bsr7.SET_ORDER=7 
AND bsr7.CUSTOMER_ID=cp.CONSUMER_ID 
LEFT JOIN survey_scores AS bsr8 
ON bsr8.SET_ORDER=8 
AND bsr8.CUSTOMER_ID=cp.CONSUMER_ID 

이 적절한 출력을 반환합니다,하지만하지만 정말 느립니다. 최적화 방법을 어떻게 제안 하시겠습니까?

+0

'EXPLAIN' 출력을 게시하십시오. – derobert

답변

3

가장 먼저 필요한 것은 survey_scores (SET_ORDER, consumer_id, score) 또는 적어도 survey_scores (SET_ORDER, consumer_id)의 색인입니다. 그러면 쿼리와도 잘 작동합니다.

또 다른 방법은 당신이 더 약간 조정할 수

SELECT cp.CONSUMER_ID, 
     MAX(CASE WHEN bsr1.SET_ORDER=1 THEN bsr1.SCORE END) AS SET_1_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=2 THEN bsr1.SCORE END) AS SET_2_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=3 THEN bsr1.SCORE END) AS SET_3_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=4 THEN bsr1.SCORE END) AS SET_4_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=5 THEN bsr1.SCORE END) AS SET_5_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=6 THEN bsr1.SCORE END) AS SET_6_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=7 THEN bsr1.SCORE END) AS SET_7_SCORE, 
     MAX(CASE WHEN bsr1.SET_ORDER=8 THEN bsr1.SCORE END) AS SET_8_SCORE 
FROM CONSUMER_PROFILE AS cp 
LEFT JOIN survey_scores AS bsr1 
ON bsr1.SET_ORDER in (1,2,3,4,5,6,7,8) 
AND bsr1.CUSTOMER_ID=cp.CONSUMER_ID 
GROUP BY cp.CONSUMER_ID 
0

될 것이다 쓰기 :

SELECT ... FROM consumer_profile as cp  
LEFT JOIN survey_scores as bsr1 
ON ((bsr1.Set_Order BETWEEN 1 AND 8) 
    AND (bsr1.Consumer_ID = cp.Consumer_ID)) 
GROUP BY cp.Consumer_ID; 

확신하는 경우는 범위 1에서 결코Set_order입니다 .. 8 (bsr1.Set_Order BETWEEN 1 AND 8) AND 부분을 삭제할 수 있습니다.

그 외 리처드의 대답은 아름다움의 것입니다.