

# 验证哪些语句使用 Aurora MySQL 的并行查询
<a name="aurora-mysql-parallel-query-verifying"></a>

 在典型操作中，您无需执行任何特殊操作即可利用并行查询。在查询满足并行查询的基本要求后，查询优化程序自动确定是否在每个特定查询中使用并行查询。

 如果您在开发或测试环境中运行试验，您可能会发现未使用并行查询，因为您的表的行数或总数据量太少。表的数据也可能完全位于缓冲池中，尤其是最近创建以执行试验的表。

 在监控或优化集群性能时，请确保确定是否在相应的上下文中使用并行查询。您可以调整数据库架构、设置、SQL 查询甚至集群拓扑和应用程序连接设置以利用该功能。

 要检查查询是否使用并行查询，请运行 [EXPLAIN](https://dev.mysql.com/doc/refman/5.7/en/execution-plan-information.html) 语句以检查查询计划（也称为“解释计划”）。有关 SQL 语句、子句和表达式如何影响并行查询的 `EXPLAIN` 输出的示例，请参阅[Aurora MySQL 中用于并行查询的 SQL 构造](aurora-mysql-parallel-query-sql.md)。

 以下示例说明了传统查询计划和并行查询计划之间的区别。此解释计划来自 TPC-H 基准中的查询 3。本节中的很多示例查询使用 TPC-H 数据集中的表。您可以从 [TPC-H 网站](http://www.tpc.org/tpch/)获取生成示例数据的表定义、查询以及 `dbgen` 程序。

```
EXPLAIN SELECT l_orderkey,
  sum(l_extendedprice * (1 - l_discount)) AS revenue,
  o_orderdate,
  o_shippriority
FROM customer,
  orders,
  lineitem
WHERE c_mktsegment = 'AUTOMOBILE'
AND c_custkey = o_custkey
AND l_orderkey = o_orderkey
AND o_orderdate < date '1995-03-13'
AND l_shipdate > date '1995-03-13'
GROUP BY l_orderkey,
  o_orderdate,
  o_shippriority
ORDER BY revenue DESC,
  o_orderdate LIMIT 10;
```

 默认情况下，查询可能具有如下所示的计划。如果您没有看到查询计划中使用的哈希联接，请确保首先开启了优化。

```
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+
| id | select_type | table    | partitions | type | possible_keys | key  | key_len | ref  | rows     | filtered | Extra                                              |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+
|  1 | SIMPLE      | customer | NULL       | ALL  | NULL          | NULL | NULL    | NULL |  1480234 |    10.00 | Using where; Using temporary; Using filesort       |
|  1 | SIMPLE      | orders   | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 14875240 |     3.33 | Using where; Using join buffer (Block Nested Loop) |
|  1 | SIMPLE      | lineitem | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 59270573 |     3.33 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+----------+------------+------+---------------+------+---------+------+----------+----------+----------------------------------------------------+
```

对于 Aurora MySQL 版本 3，您可以通过发出以下语句在会话级别开启哈希联接。

```
SET optimizer_switch='block_nested_loop=on';
```

对于 Aurora MySQL 版本 2.09 及更高版本，您可以将 `aurora_disable_hash_join` 数据库参数或数据库集群参数设置为 `0`（关闭）。关闭 `aurora_disable_hash_join` 会将 `optimizer_switch` 的值设置为 `hash_join=on`。

开启哈希连接后，尝试再次运行 `EXPLAIN` 语句。有关如何有效使用哈希联接的信息，请参阅 [使用哈希联接优化大型 Aurora MySQL 联接查询](AuroraMySQL.BestPractices.Performance.md#Aurora.BestPractices.HashJoin)。

 在开启哈希联接但关闭并行查询的情况下，查询可能具有如下所示的计划，该计划使用哈希联接而不是并行查询。

```
+----+-------------+----------+...+-----------+-----------------------------------------------------------------+
| id | select_type | table    |...| rows      | Extra                                                           |
+----+-------------+----------+...+-----------+-----------------------------------------------------------------+
|  1 | SIMPLE      | customer |...|   5798330 | Using where; Using index; Using temporary; Using filesort       |
|  1 | SIMPLE      | orders   |...| 154545408 | Using where; Using join buffer (Hash Join Outer table orders)   |
|  1 | SIMPLE      | lineitem |...| 606119300 | Using where; Using join buffer (Hash Join Outer table lineitem) |
+----+-------------+----------+...+-----------+-----------------------------------------------------------------+
```

 在开启并行查询后，该查询计划中的两个步骤可以使用并行查询优化，如 `EXPLAIN` 输出中的 `Extra` 列所示。这些步骤的 I/O 密集型和 CPU 密集型处理将向下推送到存储层。

```
+----+...+--------------------------------------------------------------------------------------------------------------------------------+
| id |...| Extra                                                                                                                          |
+----+...+--------------------------------------------------------------------------------------------------------------------------------+
|  1 |...| Using where; Using index; Using temporary; Using filesort                                                                      |
|  1 |...| Using where; Using join buffer (Hash Join Outer table orders); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra)   |
|  1 |...| Using where; Using join buffer (Hash Join Outer table lineitem); Using parallel query (4 columns, 1 filters, 1 exprs; 0 extra) |
+----+...+--------------------------------------------------------------------------------------------------------------------------------+
```

 有关如何解释并行查询的 `EXPLAIN` 输出以及并行查询可以应用到的 SQL 语句部分的信息，请参阅[Aurora MySQL 中用于并行查询的 SQL 构造](aurora-mysql-parallel-query-sql.md)。

 以下示例输出显示在具有冷缓冲池的 db.r4.2xlarge 实例上运行上述查询的结果。在使用并行查询时，查询运行速度要快得多。

**注意**  
 由于计时取决于很多环境因素，因此，您的结果可能会有所不同。请始终执行您自己的性能测试，以便在您自己的环境、工作负载等条件下确认这些结果。

```
-- Without parallel query
+------------+-------------+-------------+----------------+
| l_orderkey | revenue     | o_orderdate | o_shippriority |
+------------+-------------+-------------+----------------+
|   92511430 | 514726.4896 | 1995-03-06  |              0 |
.
.
|   28840519 | 454748.2485 | 1995-03-08  |              0 |
+------------+-------------+-------------+----------------+
10 rows in set (24 min 49.99 sec)
```

```
-- With parallel query
+------------+-------------+-------------+----------------+
| l_orderkey | revenue     | o_orderdate | o_shippriority |
+------------+-------------+-------------+----------------+
|   92511430 | 514726.4896 | 1995-03-06  |              0 |
.
.
|   28840519 | 454748.2485 | 1995-03-08  |              0 |
+------------+-------------+-------------+----------------+
10 rows in set (1 min 49.91 sec)
```

 本节中的很多示例查询使用该 TPC-H 数据集中的表，尤其是具有 2000 万行和以下定义的 `PART` 表。

```
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| p_partkey     | int(11)       | NO   | PRI | NULL    |       |
| p_name        | varchar(55)   | NO   |     | NULL    |       |
| p_mfgr        | char(25)      | NO   |     | NULL    |       |
| p_brand       | char(10)      | NO   |     | NULL    |       |
| p_type        | varchar(25)   | NO   |     | NULL    |       |
| p_size        | int(11)       | NO   |     | NULL    |       |
| p_container   | char(10)      | NO   |     | NULL    |       |
| p_retailprice | decimal(15,2) | NO   |     | NULL    |       |
| p_comment     | varchar(23)   | NO   |     | NULL    |       |
+---------------+---------------+------+-----+---------+-------+
```

 在您的工作负载条件下试验，以了解各个 SQL 语句是否可以利用并行查询。然后，使用以下监控方法帮助验证在一段时间内在实际工作负载条件下使用并行查询的频率。对于实际工作负载，还存在额外的影响因素，例如，并发限制。