我正在尝试使用子查询获得总计。 (我正在使用Metabase,它似乎不接受/处理查询中的变量)
我的查询:
SELECT date_format(t.`session_stop`, '%d') AS `session_stop`,
sum(t.`energy_used` / 1000) AS `csum`,
(
SELECT (SUM(a.`energy_used`) / 1000)
FROM `sessions` a
WHERE date_format(a.`session_stop`, '%Y-%m-%d') <= date_format(t.`session_stop`, '%Y-%m-%d')
AND str_to_date(concat(date_format(a.`session_stop`, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d')
ORDER BY str_to_date(date_format(a.`session_stop`, '%e'), '%d') ASC
) AS `sum`
FROM `sessions` t
WHERE str_to_date(concat(date_format(t.`session_stop`, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d')
GROUP BY date_format(t.`session_stop`, '%e')
ORDER BY str_to_date(date_format(t.`session_stop`, '%d'), '%d') ASC;
这需要大约1.29秒才能运行。 (总共43K行,返回14)
如果我删除sum(t.`energy_used` / 1000) AS `csum`,
行,则查询占用8分钟和40秒。
这是为什么?我宁愿没有那条线,但我也不能等待8分钟来处理查询。
(我知道我可以创建一个累积列,但我特别感兴趣的是为什么这个额外的sum()
加快了整个查询的速度)
PS。在MySQL控制台和Metabase接口上测试了它。
EXPLAIN查询:
+----+--------------------+-------+------+---------------+------+---------+------+-------+---------------------------
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
+----+--------------------+-------+------+---------------+------+---------+------+-------+---------------------------
| 1 | PRIMARY | t | ALL | NULL | NULL | NULL | NULL | 42055 | Using where; Using tempora
| 2 | DEPENDENT SUBQUERY | a | ALL | NULL | NULL | NULL | NULL | 42055 | Using where
+----+--------------------+-------+------+---------------+------+---------+------+-------+---------------------------
2 rows in set (0.00 sec)
没有额外的sum()
:
+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
| 1 | PRIMARY | t | ALL | NULL | NULL | NULL | NULL | 44976 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | a | ALL | NULL | NULL | NULL | NULL | 44976 | Using where |
+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
2 rows in set (0.00 sec)
Schema不仅仅是一个表:
session_id (INT, auto incr., prim.key) | session_stop (datetime) | energy_used (INT) |
1 | 1-1-2016 10:00:00 | 123456 |
2 | 1-1-2016 10:05:00 | 123456 |
3 | 1-2-2016 10:10:00 | 123456 |
4 | 1-2-2016 12:00:00 | 123456 |
5 | 3-3-2016 14:05:00 | 123456 |
关于互联网的一些例子显示使用WHERE子句的ID,但是我的结果很差。
答案 0 :(得分:1)
您的查询完全不相似。事实上,他们是两极分开。
如果我删除总和(t。
energy_used
/ 1000)AScsum
,行,查询 需要8分40秒。
使用SUM时,它是一个聚合。 sum(t.
energy_used / 1000)
会产生完全不同的结果,因为只选择t.energy_used
,这就是为什么查询时间存在巨大差异的原因。
还很不清楚为什么要以这种方式比较日期:
WHERE date_format(a.`session_stop`, '%Y-%m-%d') <= date_format(t.`session_stop`, '%Y-%m-%d')
为什么在比较之前用date_format转换它们?由于两个表显然都包含相同的数据类型,因此您应该能够a.session_stop <= t.session_stop
这两种情况都会更快。
由于它是不等式比较,它不是索引的良好候选者,但您仍然可以尝试在该列上创建索引以查看它是否有任何影响。
回顾一下,性能差异是因为您不仅仅是添加/删除额外的列而是添加/删除聚合。