2011-01-28 82 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条记录的数据集合,那么结果数据集合将会是100000条记录,明显需要比返回原始1000条记录更多的时间。但是如果你需要这些数据,你需要这些数据。 – HLGEM 2011-01-28 19:28:19

+0

同意,另一个原因是它停止整个查询由rdbms引擎优化。我已经看到了甲骨文的CBO与交叉连接的斗争。 (并且通常交叉连接也意味着设计有些不对); – 2011-01-29 15:58:59

回答

3

因此,您的交叉连接不是什么大问题,因为第二个内联查询只返回一行。

交叉加入“减慢速度”的方式与装载汽车减慢速度的方式相同。

确实如此,但是如果您需要搬运的东西,您可以将它们放入汽车中,如果您需要笛卡尔产品,则可以进行交叉连接。

1

如果你的问题是如果交叉加入较慢?(比什么?;)),那么简化的答案是肯定的。当然,这是一个普遍问题的一般回答。但对你而言,你需要量化速度有多慢。

出于所有实际目的,您的查询可能会尽可能快。所以要验证,在你的查询上运行解释计划(我是一个oracle的人,但我认为在mysql中运行解释计划没有那么不同,链接http://dev.mysql.com/doc/refman/5.0/en/explain.html)。

然后创建一个临时表并替换查询中的那些并再次检查计划。

注意:如果您发现您的查询解释计划足够好,则不必浪费时间进行进一步分析。