我在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
答案 0 :(得分:0)
几个想法:
DATE_FORMAT(collection.date,'%Y-%m-%d')
进行分组,但您选择的是时间(DATE_FORMAT(MIN(collection.date),'%Y-%m-%d %H:00')
)collection.date
是datetime
字段,则GROUP BY DATE(collection.date)
并在SELECT
中进行格式设置。我建议将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