2011-01-28 9 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レコードを戻すよりも明らかに時間がかかる100000レコードになります。しかし、データが必要な場合は、データが必要です。 – HLGEM

+0

また、rdbmsエンジンによってクエリ全体が最適化されるのを止めるもう一つの理由もあります。私はoracleのCBOとのクロスジョイントを見てきました。 (通常はクロスジョイントとは、デザインに問題があることを意味します) –

答えて

3

このように、2回目のインラインクエリでは1つの行しか返さないため、クロスジョインはほとんど問題になりません。

車のローディングと同じようにクロススピードが遅くなるため、スピードが遅くなります。

もちろん、移動したものが必要な場合は車にロードし、デカルト積が必要な場合はクロスジョインを行います。

+0

これを含め、すべての一般化は危険です。 – araqnid

+0

@araqnid:これは安全です。 – Quassnoi

1

クロスジョインが遅い(何よりも;;))の場合、簡略化された回答は「はい」です。もちろんこれは一般的な質問に対する非常に一般的な答えです。しかし、あなたにとっては、どのくらい遅いかを定量化する必要があります。

すべての実用的な目的のために、クエリは可能な限り速くなる可能性があります。したがって、検証するために、あなたのクエリ(私はオラクルの男ですが、私はmysqlの計画を実行していると仮定して説明プランを実行することはそれほど違いはありません。リンクhttp://dev.mysql.com/doc/refman/5.0/en/explain.html)。

次に、テンポラリテーブルを作成し、クエリ内のテンポラリテーブルを置き換えてプランを再度確認します。

注:問合せのExplain計画が十分にわかっている場合は、後で分析するために時間を浪費する必要はありません。

関連する問題