

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Amazon Redshift 中的 SQL 查询处理
<a name="query-processing"></a>

Amazon Redshift 通过分析程序和优化程序路由提交的 SQL 查询，以制订查询计划。然后，执行引擎将查询计划转换为代码并将代码发送到计算节点执行。在设计查询计划之前，了解查询处理的工作原理至关重要。

## 查询计划和执行工作流程
<a name="query-planning-and-execution-workflow"></a>

下图概要介绍查询计划和执行工作流程。



![客户端、领导节点和计算节点之间的查询计划和执行工作流程。](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/query-lifecycle-redshift/images/query-planning-execution-workflow.png)


下图显示了如下工作流：

1. Amazon Redshift 集群中的领导节点接收查询并解析 SQL 语句。

1. 解析器生成初始查询树，后者是原始查询的逻辑表示。

1. 查询优化器获取初始查询树并对其进行评估，分析表统计数据以确定联接顺序和谓词选择性，并在必要时重写查询以最大限度地提高其效率。有时，一个查询可以在后台写成多个依赖语句。

1. 优化程序会生成一个查询计划以最佳性能进行执行（如果上一步导致多个查询，则生成多个查询计划）。查询计划指定执行选项，如执行顺序、网络操作、联接类型、联接顺序、聚合选项和数据分配。

1. 查询计划包含运行查询所需的各个操作的信息。您可以使用 `EXPLAIN` 命令查看查询计划。查询计划是分析和优化复杂查询的基本工具。

1. 查询优化器将查询计划发送到执行引擎。执行引擎检查已编译计划缓存中是否存在查询计划匹配项；如果找到，则使用已编译的缓存。否则，执行引擎将查询计划转换为步骤、分段和流：
   + *步骤*是在查询执行期间发生的单个操作，由标签（例如 `scan`、`dist`、`hjoin` 或 `merge`）标识。步骤是最小的单元。您可以组合步骤，以使计算节点能够执行查询、联接或其他数据库操作。
   + *分段*是指查询的分段，组合了可通过一个过程完成的多个步骤。分段是计算节点切片可执行的最小编译单元。切片是 Amazon Redshift 中并行处理的单元。
   + *流*是要分配到可用计算节点切片上的分段的集合。流中的分段跨节点切片并行运行。因此，同一分段的同一步骤也会在多个切片中并行执行。

1. 代码生成器接收转换的计划，并为每个分段生成一个 C\+\+ 函数。

1. 生成的 C\+\+ 函数由 GNU 编译器集合编译并转换为 O（`.o`）文件。

1. 编译后的代码（O 文件）将运行。编译的代码运行速度比解释的代码快，并且使用的计算容量更少。

1. 然后，将编译的 O 文件会广播到计算节点。

1. 每个计算节点由多个计算切片组成。计算切片将并行运行查询分段。Amazon Redshift 利用优化的网络通信、内存和磁盘管理，将中间结果从一个查询计划步骤传递到下一个。这还有助于加快查询执行速度。请考虑以下事项：
   + 步骤 6、7、8、9、10、11 对每个流执行一次。
   + 引擎为一个流创建可执行分段，并将这些分段发送到计算节点。
   + 上一个流的分段完成后，引擎会生成下一个流的分段。通过这种方式，引擎可以分析先前流中发生的情况（例如，操作是否基于磁盘），以影响下一个流中分段的生成。

1. 计算节点完成后，它们会将查询结果返回到领导节点以进行最终处理。领导节点将数据合并到单个结果集中，并解决任何所需的排序或聚合。

1. 领导节点将结果返回至客户端。

下图显示流、分段、步骤和计算节点切片的执行工作流程。记住以下内容：
+ 分段中的步骤按顺序运行。
+ 流中的分段并行运行。
+ 流按顺序运行。
+ 计算节点切片并行运行。

下图显示流、分段和步骤的可视化表示。每个分段包含多个步骤，每个流包含多个分段。



![每个流包含多个分段，而每个分段又包含多个步骤。](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/query-lifecycle-redshift/images/streams-segments-steps.png)


下图显示查询执行和计算节点切片的可视化表示。每个计算节点都包含多个切片、流、分段和步骤。



![每个计算节点中的切片、流、分段和步骤。](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/query-lifecycle-redshift/images/compute-nodes.png)


## 其他注意事项
<a name="additional-considerations"></a>

关于查询处理，我们建议您考虑以下事项：
+ 缓存的编译代码将跨同一个集群中的多个会话进行共享，因此同一查询后续执行的速度将更快，通常甚至会使用不同的参数。
+ 对查询进行基准测试时，我们建议您始终比较查询第二次执行的时间，因为第一次执行时间包括编译代码的开销。有关更多信息，请参阅《Query best practices for Amazon Redshift》**指南中的 [Query performance factors](https://docs.aws.amazon.com/prescriptive-guidance/latest/query-best-practices-redshift/query-performance-factors.html)。
+ 如有必要，计算节点可能会在查询执行期间将某些数据返回到领导节点。例如，如果您有一个包含 `LIMIT` 子句的子查询，则在数据在集群间重新分配以进一步处理前会在领导节点上应用该限制。