【发布时间】:2011-09-26 14:03:31
【问题描述】:
我有一个带有列的表格:
CREATE TABLE aggregates (
a VARHCAR,
b VARCHAR,
c VARCHAR,
metric INT
KEY test (a, b, c, metric)
);
如果我进行如下查询:
SELECT b, c, SUM(metric) metric
FROM aggregates
WHERE a IN ('a', 'couple', 'of', 'values')
GROUP BY b, c
ORDER BY b, c
查询耗时10秒,解释为:
+----+-------------+------------+-------+---------------+------+---------+------+--------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+------+---------+------+--------+-----------------------------------------------------------+
| 1 | SIMPLE | aggregates | range | test | test | 767 | NULL | 582383 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+------------+-------+---------------+------+---------+------+--------+-----------------------------------------------------------+
如果我还按 a 列分组/排序,所以它不需要临时/文件排序,但然后我自己在另一个查询中做同样的事情:
SELECT b, c, SUM(metric) metric
FROM (
SELECT a, b, c, SUM(metric) metric
FROM aggregates
WHERE a IN ('a', 'couple', 'of', 'values')
GROUP BY a, b, c
ORDER BY a, b, c
) t
GROUP BY b, c
ORDER BY b, c
查询耗时 1 秒,解释为:
+----+-------------+------------+-------+---------------+------+---------+------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+------+---------+------+--------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 252 | Using temporary; Using filesort |
| 2 | DERIVED | aggregates | range | test | test | 767 | NULL | 582383 | Using where; Using index |
+----+-------------+------------+-------+---------------+------+---------+------+--------+---------------------------------+
这是为什么?为什么我在单独的外部查询中进行分组而不是在一个单独的查询中进行分组会更快?
【问题讨论】:
-
这两个查询是否显示相同的结果?您是否在第二次查询中忘记了
metric? -
恕我直言,这很可能与 MySQL 的实现方式有关,在其他数据库引擎上可能无法像这样工作。
-
你确定性能差异不仅仅是数据库缓存吗?
-
第二个查询会在 MySQL 和任何其他 RDBMS 中引发错误。在“复制粘贴更改名称”期间出现了问题。
-
ypercube:是的,结果相同。对不起,我在简化时忘记了公制。它在那里,我会添加它。
标签: mysql performance optimization