Mysql内连接与

时间:2017-02-07 11:39:55

标签: mysql optimization explain

    SELECT pm.team,
       pm.username,
       count(DISTINCT if(offer_pm.revenue>0.0,adv.adv_name,NULL)) AS adv_count,
       sum(offer_pm.click),
       sum(offer_pm.install),
       sum(offer_pm.revenue),
       sum(offer_pm.cost)
FROM (pm pm
      INNER JOIN offer_pm_adv_day offer_pm ON offer_pm.pm_id=pm.id)
INNER JOIN advertiser adv ON offer_pm.adv_id=adv.id
WHERE offer_pm.logdate>='2016-01-01'
    AND offer_pm.logdate<='2017-01-01'
GROUP BY pm.team,
         pm.username

如果有条件offer_pm.logdate>='2016-01-01' and offer_pm.logdate<='2017-01-01' 下面是sql的解释。成本时间很长(20s)

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: offer_pm
         type: range
possible_keys: PRIMARY,adv_id_index,logdate_index
          key: PRIMARY
      key_len: 3
          ref: NULL
         rows: 713003
        Extra: Using where; Using temporary; Using filesort    -->Useing where 
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: pm
         type: eq_ref
possible_keys: PRIMARY,uniq_name_team
          key: PRIMARY
      key_len: 4
          ref: summary_report_refactor2.offer_pm.pm_id
         rows: 1
        Extra: Using where    

*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: adv
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: summary_report_refactor2.offer_pm.adv_id
         rows: 1
        Extra: Using where

但是sql

SELECT pm.team,
       pm.username,
       count(DISTINCT if(offer_pm.revenue>0.0,adv.adv_name,NULL)) AS adv_count,
       sum(offer_pm.click),
       sum(offer_pm.install),
       sum(offer_pm.revenue),
       sum(offer_pm.cost)
FROM (pm pm
      INNER JOIN offer_pm_adv_day offer_pm ON offer_pm.pm_id=pm.id)
INNER JOIN advertiser adv ON offer_pm.adv_id=adv.id
GROUP BY pm.team,
         pm.username

哪个没有条件。

费用时间是2秒。解释是

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: pm
         type: index
possible_keys: PRIMARY,uniq_name_team
          key: uniq_name_team
      key_len: 604
          ref: NULL
         rows: 91
        Extra: Using index; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: offer_pm
         type: ref
possible_keys: adv_id_index,pm_id_index
          key: pm_id_index
      key_len: 4
          ref: summary_report_refactor2.pm.id
         rows: 10042
        Extra: Using index condition
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: adv
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: summary_report_refactor2.offer_pm.adv_id
         rows: 1
        Extra: Using where

BTW,logdate列上有一个索引。

1 个答案:

答案 0 :(得分:0)

如果您在logdate上有索引,请尝试以下查询:

SELECT straight_join pm.team,
       pm.username,
       count(DISTINCT if(offer_pm.revenue>0.0,adv.adv_name,NULL)) AS adv_count,
       sum(offer_pm.click),
       sum(offer_pm.install),
       sum(offer_pm.revenue),
       sum(offer_pm.cost)
FROM offer_pm_adv_day offer_pm
INNER JOIN pm ON offer_pm.pm_id=pm.id
INNER JOIN advertiser adv ON offer_pm.adv_id=adv.id
WHERE offer_pm.logdate>='2016-01-01'
    AND offer_pm.logdate<='2017-01-01'
GROUP BY pm.team,
         pm.username ;

它基本上与表的组织方式有关。 以及执行计划员使用的密钥。

通过使用straight_join,您可以强制某种方式连接表,有时可以稍微改善执行时间。 您还可以查看mysql force keyforce index选项。

或者您可以修改加入表格的方式:

SELECT pm.team,
       pm.username,
       count(DISTINCT if(offer_pm.revenue>0.0,adv.adv_name,NULL)) AS adv_count,
       sum(offer_pm.click),
       sum(offer_pm.install),
       sum(offer_pm.revenue),
       sum(offer_pm.cost)
FROM pm
INNER JOIN offer_pm_adv_day offer_pm ON offer_pm.pm_id=pm.id
    AND offer_pm.logdate BETWEEN '2016-01-01' AND '2017-01-01'
INNER JOIN advertiser adv ON offer_pm.adv_id=adv.id
GROUP BY pm.team,
         pm.username