两个查询比一个快?

Jak*_*čar 9 mysql optimization performance

我有一个列表:

CREATE TABLE aggregates (
    a VARHCAR,
    b VARCHAR,
    c VARCHAR,
    metric INT
    KEY test (a, b, c, metric)
);
Run Code Online (Sandbox Code Playgroud)

如果我查询如下:

SELECT b, c, SUM(metric) metric
FROM aggregates
WHERE a IN ('a', 'couple', 'of', 'values')
GROUP BY b, c
ORDER BY b, c
Run Code Online (Sandbox Code Playgroud)

查询需要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 |
+----+-------------+------------+-------+---------------+------+---------+------+--------+-----------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

如果我也按列/按顺序分组,那么它不需要临时/ filesort,但是我自己在另一个查询中执行相同的操作:

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
Run Code Online (Sandbox Code Playgroud)

查询需要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        |
+----+-------------+------------+-------+---------------+------+---------+------+--------+---------------------------------+
Run Code Online (Sandbox Code Playgroud)

为什么是这样?如果我在一个单独的外部查询中进行分组,而不是只在一个中进行分组,为什么它会更快?

Ser*_*lis 2

SQL 的工作方式是每一步拥有的数据越少,查询执行的速度就越快。因为您首先在内部查询中进行分组,所以您将删除外部查询不再需要处理的大量数据。

SQL 优化应该可以回答您的一些问题。但要记住的最重要的一点是,您可以在查询早期消除的内容越多,查询运行的速度就越快。

数据库还有一部分尝试不同的方式来运行查询。服务器的这一部分在大多数情况下会选择最快的路径,但在查询中更具体可以真正帮助它。更多相关内容请参见本页:数据库系统读物

看看你的解释,如此大量的行上的文件排序可能会对查询造成很大的损害。因为主查询(第二个查询的外部范围)中的行将在内存表中工作。