如何优化这个以连接为列的mysql查询?

时间:2015-09-21 16:42:00

标签: mysql optimization

此查询花费超过4秒的时间来执行查杀页面上的性能。 查询正在为一个特定月份的产品执行一个点数总和获得最大点数。目的是显示按点数总和排序的给定月份的排名。

SELECT eriginal_asin, DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') as date_time, SUM(maxpoints) as points, `o1`.`value` as value,
            `o2`.`value` as value1, `o3`.`value` as value2, `o4`.`value` as value3, `o5`.`value` as value4, `o6`.`value` as value5,
            `o7`.`value` as value6, `o8`.`value` as value7, `o9`.`value` as value8, `o10`.`value` as value9, `o11`.`value` as value10,
            `o12`.`value` as value11, `o13`.`value` as value12, `o14`.`value` as value13, `o15`.`value` as value14, `o16`.`value` as value15,
            `o17`.`value` as value16, property.id, user.name_surname, user.name_last
            from
                (SELECT id, eriginal_asin, max(points) as maxpoints, DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') as date_time
                from ranking
                where date_time >= '2015-09-01'
                        and date_time <= '2015-09-30 23:59:59'
                and points > 0
                group by eriginal_asin, region, date(date_time)
            )rankmax, property
            LEFT JOIN `property_user` ON `property`.`id` = `property_user`.`property_id`
            LEFT JOIN `user` ON `property_user`.`user_id` = `user`.`id`
            LEFT JOIN `property_value` o1 ON `property`.`id` = `o1`.`property_id` and o1.option_id = 17
            LEFT JOIN `property_value` o2 ON `property`.`id` = `o2`.`property_id` and o2.option_id = 10
            LEFT JOIN `property_value` o3 ON `property`.`id` = `o3`.`property_id` and o3.option_id = 54
            LEFT JOIN `property_value` o4 ON `property`.`id` = `o4`.`property_id` and o4.option_id = 64
            LEFT JOIN `property_value` o5 ON `property`.`id` = `o5`.`property_id` and o5.option_id = 65
            LEFT JOIN `property_value` o6 ON `property`.`id` = `o6`.`property_id` and o6.option_id = 5
            LEFT JOIN `property_value` o7 ON `property`.`id` = `o7`.`property_id` and o7.option_id = 6
            LEFT JOIN `property_value` o8 ON `property`.`id` = `o8`.`property_id` and o8.option_id = 10
            LEFT JOIN `property_value` o9 ON `property`.`id` = `o9`.`property_id` and o9.option_id = 63
            LEFT JOIN `property_value` o10 ON `property`.`id` = `o10`.`property_id` and o10.option_id = 55
            LEFT JOIN `property_value` o11 ON `property`.`id` = `o11`.`property_id` and o11.option_id = 56
            LEFT JOIN `property_value` o12 ON `property`.`id` = `o12`.`property_id` and o12.option_id = 57
            LEFT JOIN `property_value` o13 ON `property`.`id` = `o13`.`property_id` and o13.option_id = 58
            LEFT JOIN `property_value` o14 ON `property`.`id` = `o14`.`property_id` and o14.option_id = 59
            LEFT JOIN `property_value` o15 ON `property`.`id` = `o15`.`property_id` and o15.option_id = 60
            LEFT JOIN `property_value` o16 ON `property`.`id` = `o16`.`property_id` and o16.option_id = 61
            LEFT JOIN `property_value` o17 ON `property`.`id` = `o17`.`property_id` and o17.option_id = 62
            where property.is_activated = 1
            and o1.value = eriginal_asin
            GROUP BY DATE(date_time), eriginal_asin
            order by points desc 

2 个答案:

答案 0 :(得分:0)

有一件事是,你可以用一个 LEFT JOIN 来做到这一点。我已经制作了一个样本(不是所有列)来测试它是否更好

SELECT eriginal_asin,
       DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') AS date_time,
       SUM(maxpoints) AS points,
       coalesce( IF( o.property_id = 17,  `o`.`value`, NULL )) AS value_1,
       coalesce(IF (o.property_id = 10,  `o`.`value`, NULL )) AS value_
       coalesce(IF (o.property_id = 54,  `o`.`value`, NULL )) AS value_3,
       coalesce(IF (o.property_id = 64,  `o`.`value`, NULL )) AS value_4,

       property.id,
       user.name_surname,
       user.name_last
FROM
  (SELECT id,
          eriginal_asin,
          max(points) AS maxpoints,
                         DATE_FORMAT(date_time,'%m/%d/%Y %h:%i:%s') AS date_time
   FROM ranking
   WHERE date_time >= '2015-09-01'
     AND date_time <= '2015-09-30 23:59:59'
     AND points > 0
   GROUP BY eriginal_asin,
            region,
            date(date_time) )rankmax,
     property
LEFT JOIN `property_user` ON `property`.`id` = `property_user`.`property_id`
LEFT JOIN `user` ON `property_user`.`user_id` = `user`.`id`
LEFT JOIN `property_value` o ON `property`.`id` = `o`.`property_id`

WHERE property.is_activated = 1
  AND o1.value = eriginal_asin
GROUP BY o.property_id,
         DATE(date_time),
         eriginal_asin
ORDER BY points DESC;

答案 1 :(得分:0)

一些事情......你能否提供你的&#34; Property_Value&#34;的一些样本数据。表记录......&#34;值是什么&#34;。 Ranking.ID ...这是与该属性相关联的ID吗?你没有连接条件,这可能导致笛卡尔结果。

排名表是否有&#34; Property_ID&#34;要加入的列。你的property_value表上有索引(value,id,option_id)......组合/多字段索引也会有很大的帮助。

此外,尚不清楚属性ID基于RankMax表的确切位置/位置 - 或者属性表是否具有&#34; eriginal_asin&#34;专栏(疑问)。

现有的表格结构和一些示例数据(数据的空格格式而不是首选的标签)可以帮助我和/或其他人帮助您。

仅数据示例(您可以复制/粘贴原始问题并根据需要调整内容),但某些地方确实缺少您的加入条件。

Property Table
ID   Is_Activiated   OtherDescript
1    1               Test Sample
2    0               Another Property
3    1               last

User Table
ID   UserName

PropertyUser Table
ID   Property_ID
1    3          
2    1          
3    2          

Property_value table
ID   Property_ID   Option_ID   Value
1    3             17          blah
1    3             10          another
1    3             54          blah 2
相关问题