

 从补丁 198 开始，Amazon Redshift 将不再支持创建新的 Python UDF。现有的 Python UDF 将继续正常运行至 2026 年 6 月 30 日。有关更多信息，请参阅[博客文章](https://aws.amazon.com/blogs/big-data/amazon-redshift-python-user-defined-functions-will-reach-end-of-support-after-june-30-2026/)。

# EXPLAIN
<a name="r_EXPLAIN"></a>

显示查询语句的执行计划，而不运行查询。有关查询分析工作流程的信息，请参阅[查询分析工作流程](c-query-analysis-process.md)。

## 语法
<a name="r_EXPLAIN-synopsis"></a>

```
EXPLAIN [ VERBOSE ] query
```

## 参数
<a name="r_EXPLAIN-parameters"></a>

VERBOSE   
显示完整的查询计划，而不只是摘要。

 *query*   
要解释的查询语句。查询可以是 SELECT、INSERT、CREATE TABLE AS、UPDATE 或 DELETE 语句。

## 使用说明
<a name="r_EXPLAIN-usage-notes"></a>

在创建临时表时需要花费一定的时间，因此 EXPLAIN 性能有时会受到影响。例如，使用公共子表达式优化的查询需要创建和分析临时表，以返回 EXPLAIN 输出。查询计划依赖于临时表的 schema 和统计数据。因此，此类查询的 EXPLAIN 命令的运行时间可能会超过预期。

您只能对以下命令使用 EXPLAIN：
+ SELECT
+ SELECT INTO
+ CREATE TABLE AS
+ INSERT
+ UPDATE
+ DELETE

如果您对其他 SQL 命令（例如数据定义语言 (DDL) 或数据库操作）使用 EXPLAIN 命令，则该命令将失败。

Amazon Redshift 使用 EXPLAIN 输出相对单位成本来选择查询计划。Amazon Redshift 会比较各种资源估算值的大小来确定计划。

## 查询计划和执行步骤
<a name="r_EXPLAIN-query-planning-and-execution-steps"></a>

特定 Amazon Redshift 查询语句的执行计划会将查询的执行和计算细分为一系列单独的步骤和表操作，它们最后为该查询生成一个最终结果集。有关查询计划的信息，请参阅[查询处理](c-query-processing.md)。

下表提供了步骤的汇总，Amazon Redshift 可以针对用户提交供执行的任何查询，使用这些步骤来制定执行计划。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/redshift/latest/dg/r_EXPLAIN.html)

## 将 EXPLAIN 用于 RLS
<a name="r_EXPLAIN-RLS"></a>

如果查询包含受行级别安全性 (RLS) 策略约束的表，则 EXPLAIN 将显示一个特殊的 RLS SecureScan 节点。Amazon Redshift 还会将相同的节点类型记录到 STL\$1EXPLAIN 系统表中。EXPLAIN 不会显示应用于 dim\$1tbl 的 RLS 谓词。RLS SecureScan 节点类型用作执行计划包含当前用户不可见的其他操作的指示器。

以下示例说明了 RLS SecureScan 节点。

```
EXPLAIN
SELECT D.cint
FROM fact_tbl F INNER JOIN dim_tbl D ON F.k_dim = D.k
WHERE F.k_dim / 10 > 0;
                               QUERY PLAN
------------------------------------------------------------------------
 XN Hash Join DS_DIST_ALL_NONE  (cost=0.08..0.25 rows=1 width=4)
   Hash Cond: ("outer".k_dim = "inner"."k")
   ->  *XN* *RLS SecureScan f  (cost=0.00..0.14 rows=2 width=4)*
         Filter: ((k_dim / 10) > 0)
   ->  XN Hash  (cost=0.07..0.07 rows=2 width=8)
         ->  XN Seq Scan on dim_tbl d  (cost=0.00..0.07 rows=2 width=8)
               Filter: (("k" / 10) > 0)
```

为了能够对受 RLS 约束的查询计划进行全面调查，Amazon Redshift 提供了 EXPLAIN RLS 系统权限。被授予此权限的用户可以检查还包含 RLS 谓词的完整查询计划。

以下示例说明了 RLS SecureScan 节点下方的额外顺序扫描，该顺序扫描还包括 RLS 策略谓词 (k\$1dim > 1)。

```
EXPLAIN SELECT D.cint
FROM fact_tbl F INNER JOIN dim_tbl D ON F.k_dim = D.k
WHERE F.k_dim / 10 > 0;
                                   QUERY PLAN
---------------------------------------------------------------------------------
 XN Hash Join DS_DIST_ALL_NONE  (cost=0.08..0.25 rows=1 width=4)
   Hash Cond: ("outer".k_dim = "inner"."k")
   *->  XN RLS SecureScan f  (cost=0.00..0.14 rows=2 width=4)
         Filter: ((k_dim / 10) > 0)*
         ->  *XN* *Seq Scan on fact_tbl rls_table  (cost=0.00..0.06 rows=5 width=8)
               Filter: (k_dim > 1)*
   ->  XN Hash  (cost=0.07..0.07 rows=2 width=8)
         ->  XN Seq Scan on dim_tbl d  (cost=0.00..0.07 rows=2 width=8)
               Filter: (("k" / 10) > 0)
```

在向用户授予 EXPLAIN RLS 权限的同时，Amazon Redshift 会在 STL\$1EXPLAIN 系统表中记录包括 RLS 谓词在内的完整查询计划。在未授予此权限时运行的查询将在没有 RLS 内部构件的情况下被记录。授予或删除 EXPLAIN RLS 权限不会改变 Amazon Redshift 为之前的查询记录到 STL\$1EXPLAIN 的内容。

### 受 AWS Lake Formation-RLS 保护的 Redshift 关系
<a name="r_EXPLAIN_RLS-LF"></a>

以下示例说明了 LF SecureScan 节点，您可以使用它来查看 Lake Formation-RLS 关系。

```
EXPLAIN
SELECT *
FROM lf_db.public.t_share
WHERE a > 1;
QUERY PLAN
---------------------------------------------------------------
XN LF SecureScan t_share  (cost=0.00..0.02 rows=2 width=11)
(2 rows)
```

## 示例
<a name="r_EXPLAIN-examples"></a>

**注意**  
对于这些示例，输出样本可能有所不同，具体取决于 Amazon Redshift 配置。

以下示例为从 EVENT 和 VENUE 表中选择 EVENTID、EVENTNAME、VENUEID 和 VENUENAME 的查询返回查询计划：

```
explain
select eventid, eventname, event.venueid, venuename
from event, venue
where event.venueid = venue.venueid;
```

```
                                QUERY PLAN
--------------------------------------------------------------------------
XN Hash Join DS_DIST_OUTER  (cost=2.52..58653620.93 rows=8712 width=43)
Hash Cond: ("outer".venueid = "inner".venueid)
->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=23)
->  XN Hash  (cost=2.02..2.02 rows=202 width=22)
->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=22)
(5 rows)
```

以下示例使用详细输出为同一查询返回查询计划：

```
explain verbose
select eventid, eventname, event.venueid, venuename
from event, venue
where event.venueid = venue.venueid;
```

```
                                QUERY PLAN
--------------------------------------------------------------------------
{HASHJOIN
:startup_cost 2.52
:total_cost 58653620.93
:plan_rows 8712
:plan_width 43
:best_pathkeys <>
:dist_info DS_DIST_OUTER
:dist_info.dist_keys (
TARGETENTRY
{
VAR
:varno 2
:varattno 1
...

XN Hash Join DS_DIST_OUTER  (cost=2.52..58653620.93 rows=8712 width=43)
Hash Cond: ("outer".venueid = "inner".venueid)
->  XN Seq Scan on event  (cost=0.00..87.98 rows=8798 width=23)
->  XN Hash  (cost=2.02..2.02 rows=202 width=22)
->  XN Seq Scan on venue  (cost=0.00..2.02 rows=202 width=22)
(519 rows)
```

以下示例返回 CREATE TABLE AS (CTAS) 语句的查询计划：

```
explain create table venue_nonulls as
select * from venue
where venueseats is not null;

QUERY PLAN
-----------------------------------------------------------
XN Seq Scan on venue  (cost=0.00..2.02 rows=187 width=45)
Filter: (venueseats IS NOT NULL)
(2 rows)
```