mysql查询性能SUM,按日期分组

时间:2012-09-26 22:51:09

标签: mysql performance group-by sum

我在mysql数据库中有这个查询。查询大约需要6秒才能运行~2~200万行。我有日期索引,uniqueuserid,collectiontype。

如何在mysql中提高此查询的性能?

select 
DATE_FORMAT(MIN(collection.date),'%Y-%m-%d %H:00') as date, 
COUNT(distinct collection.uniqueuserid) as convertingusers, 
SUM(case when collection.type = 1 then valueofitem end) as valueofitem, 
SUM(case when collection.type = 1 then 1 end) as numofitems, 
SUM(case when collection.type = 1 and collection.network = 1 then collection.valueofitem end) as col1valueofitem, 
SUM(case when collection.type = 1 and collection.network = 1 then 1 end) as col1numofitem, 
SUM(case when collection.type = 1 and collection.network = 2 then collection.valueofitem end) as col2valueofitem, 
SUM(case when collection.type = 1 and collection.network = 2 then 1 end) as col2numofitem, 
SUM(case when collection.type = 1 and collection.network = 3 then collection.valueofitem end) as col3valueofitem, 
SUM(case when collection.type = 1 and collection.network = 3 then 1 end) as col3numofitem, 
SUM(case when collection.type = 2 then collection.valueofitem end) as collectiontypeB, 
SUM(case when collection.type = 3 then collection.valueofitem end) as collectiontypeC,
COUNT(distinct collection.uniqueuserid) as convertingusers 

from collection
where collection.date > date_sub(now(),INTERVAL 3 WEEK) 
group by DATE_FORMAT(collection.date,'%Y-%m-%d') order by collection.date DESC limit 500

根据要求,我在查询

之前使用“EXPLAIN”运行分析
id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   PRIMARY     ALL                 1196352 Using temporary; Using filesort
2   DERIVED collection  ALL                 1196352 

1 个答案:

答案 0 :(得分:0)

几个想法:

  1. 您正按DATE_FORMAT(collection.date,'%Y-%m-%d')进行分组,但您选择的是时间(DATE_FORMAT(MIN(collection.date),'%Y-%m-%d %H:00')
  2. 如果collection.datedatetime字段,则GROUP BY DATE(collection.date)并在SELECT中进行格式设置。
  3. 我建议将CASE放入子查询中,然后像这样执行汇总(您需要添加列别名):

    SELECT DATE_FORMAT(a.date,'%Y-%m-%d %H:00') AS date,
        COUNT(a.uniqueuserid) AS convertingusers, 
        SUM(a.valueofitem),
        SUM(a.numofitems),
        SUM(a.col1valueofitem),
        SUM(a.col1numofitem),
        SUM(a.col2valueofitem),
        SUM(a.col2numofitem),
        SUM(a.col3valueofitem),
        SUM(a.col3numofitem),
        SUM(a.collectiontypeB)
    FROM
        (SELECT collection.date AS date,
            collection.uniqueuserid AS convertingusers,
            CASE
            WHEN collection.type = 1
                THEN valueofitem
            END AS valueofitem,
            CASE
            WHEN collection.type = 1
                THEN 1
            END AS numofitems,
            CASE
            WHEN collection.type = 1 AND collection.network = 1 
                THEN collection.valueofitem
            END AS col1valueofitem,
            CASE
            WHEN collection.type = 1 AND collection.network = 1
                THEN 1
            END AS col1numofitem,
            CASE
            WHEN collection.type = 1 AND collection.network = 2
                THEN collection.valueofitem
            END AS col2valueofitem,
            CASE
            WHEN collection.type = 1 AND collection.network = 2
                THEN 1
            END AS col2numofitem,
            CASE
            WHEN collection.type = 1 AND collection.network = 3
                THEN collection.valueofitem
            END AS col3valueofitem,
            CASE
            WHEN collection.type = 1 AND collection.network = 3
                THEN 1
            END AS col3numofitem,
            CASE
            WHEN collection.type = 2
                THEN collection.valueofitem
            END AS collectiontypeB,
            CASE
                WHEN collection.type = 3
                THEN collection.valueofitem
            END AS collectiontypeC
        FROM collection
        WHERE collection.date > DATE_SUB(NOW(), INTERVAL 3 WEEK)) a
    GROUP BY DATE(a.date)
    ORDER BY a.date DESC
    LIMIT 500