2011-01-28 6 views
3

크로스 조인이 포함 된 쿼리를 최적화하려고합니다. 파생 된 테이블과 교차 조인을 진행한다는 큰 쿼리가 있습니다.SQL에서 교차 조인 제거

파생 테이블을보기로 바꾸면 쿼리 속도가 빨라지겠습니까? 심지어는 영구 테이블에 그 정보를 캡처합니까?

여기에 긴 쿼리 내 쿼리

SELECT VIEWER_ID, 
     QUESTION_ID, 
     ANSWER_ID, 
     sum(ANSWER_SCORE) AS ANSWER_SCORE_SUMMED 
FROM(SELECT cr.COMMUNICATIONS_ID AS ANSWER_ID, 
     cr.CONSUMER_ID as VIEWER_ID, 
     nc.PARENT_COMMUNICATIONS_ID AS QUESTION_ID, 
     case when cr.CONSUMER_ID= nc.SENDER_CONSUMER_ID then 3*((24/(((UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(cal.LAST_MOD_TIME)+3600)/3600))*(ces.EXPERT_SCORE * cirm.CONSUMER_RATING) + (12.5 * scs.SIMILARITY)* (1 - EXP(-0.5 * (cal.TIPS_AMOUNT/ATV.AVG_TIPS)) + .15))) 
      else ((24/(((UNIX_TIMESTAMP(NOW())-UNIX_TIMESTAMP(cal.LAST_MOD_TIME)+3600)/3600))*(ces.EXPERT_SCORE * cirm.CONSUMER_RATING) + (12.5 * scs.SIMILARITY)* (1 - EXP(-0.5 * (cal.TIPS_AMOUNT/ATV.AVG_TIPS)) + .15))) 
     end as ANSWER_SCORE 
FROM (SELECT 234 AS CONSUMER_ID, 
      ACTION_LOG_ID, 
      COMMUNICATIONS_ID 
    FROM consumer_action_log 
    WHERE COMM_TYPE_ID=4) AS cr 
JOIN network_communications AS nc 
    ON cr.COMMUNICATIONS_ID=nc.COMMUNICATIONS_ID 
JOIN consumer_action_log AS cal 
    ON cr.ACTION_LOG_ID=cal.ACTION_LOG_ID 
JOIN communication_interest_mapping AS cim 
    ON nc.PARENT_COMMUNICATIONS_ID=cim.COMMUNICATION_ID 
JOIN consumer_interest_rating_mapping AS cirm 
    ON cr.CONSUMER_ID=cirm.CONSUMER_ID 
    AND cim.CONSUMER_INTEREST_EXPERT_ID=cirm.CONSUMER_INTEREST_ID 
JOIN consumer_expert_score AS ces 
    ON nc.SENDER_CONSUMER_ID=ces.CONSUMER_ID 
    AND cim.CONSUMER_INTEREST_EXPERT_ID=ces.CONSUMER_EXPERT_ID 
JOIN survey_customer_similarity AS scs 
    ON cr.CONSUMER_ID=scs.CONSUMER_ID_2 
    AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_1 
    OR cr.CONSUMER_ID=scs.CONSUMER_ID_1 
    AND cal.SENDER_CONSUMER_ID=scs.CONSUMER_ID_2 
CROSS JOIN 
    (
     SELECT AVG(cal.TIPS_AMOUNT) AS AVG_TIPS 
     FROM CONSUMER_ACTION_LOG AS cal 
     JOIN (SELECT 234 AS CONSUMER_ID, 
        ACTION_LOG_ID, 
        COMMUNICATIONS_ID 
       FROM consumer_action_log 
       WHERE COMM_TYPE_ID=4) AS cr 
     ON cal.SENDER_CONSUMER_ID=cr.consumer_id 
    ) ATV) AS ASM 
GROUP BY ANSWER_ID 
ORDER BY ANSWER_SCORE_SUMMED DESC; 

, 그래서 필요가 모든 것을 읽을 수 있습니다. 요지는 단순히 교차 결합이 있다는 것입니다. 나는 SQL에 익숙하지 않지만 교차 결합으로 속도가 느려진다는 말을 들었다.

+0

크로스 크로스 조인 속도가 느려지면 많은 레코드가 반환됩니다. 교차 결합이 100 개의 레코드가있는 테이블에 대해 1000 개의 레코드가있는 데이터 세트에 합류한다고 가정하면, 결과 데이터 세트는 원본 1000 개의 레코드를 반환하는 것보다 더 많은 시간이 걸리는 100,000 개의 레코드가됩니다. 그러나 데이터가 필요하면 데이터가 필요합니다. – HLGEM

+0

또한 동의하고 또 다른 이유는 rdbms 엔진이 전체 쿼리를 최적화하지 못하게하기 때문입니다. 나는 오라클의 크로스 조인에 대한 CBO 투쟁을 보았습니다. (일반적으로 크로스 조인은 디자인과 관련이없는 무언가가 있음을 의미합니다.) –

답변

3

이와 같이, 두 번째 인라인 쿼리는 한 행만 반환하기 때문에 교차 조인은별로 중요하지 않습니다.

차를 넣는 것과 같은 방식으로 교차 속도가 느려지므로 속도가 느려집니다.

물론 움직이는 물건이 필요하다면 차에 넣어야하고, 데카르트 제품이 필요한 경우 크로스 조인을해야합니다.

+0

모든 일반화 작업은이 작업을 포함하여 위험합니다. – araqnid

+0

@araqnid :이 사람은 안전합니다. – Quassnoi

1

크로스 조인 속도가 느린 경우 (무엇보다?)) 간단한 대답은 '예'입니다. 물론 이것은 일반적인 질문에 대한 매우 일반적인 대답입니다. 그러나 당신을 위해, 당신은 얼마나 천천히 계량해야합니다.

모든 실제적인 목적으로 쿼리는 최대한 빨리 수행 될 수 있습니다. 유효성을 검사하기 위해 쿼리에 대한 Explain 계획을 실행하십시오 (저는 Oracle 녀석입니다. 그러나 mysql에서 실행 계획을 설명하는 것이 그다지 다르지 않다고 가정합니다.) 링크 http://dev.mysql.com/doc/refman/5.0/en/explain.html).

그런 다음 임시 테이블을 만들고 쿼리의 테이블을 바꾸고 계획을 다시 확인하십시오.

주 : 조회에 대한 Explain 플랜이 충분하면 분석을 위해 시간을 낭비 할 필요가 없습니다.