

 从补丁 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/)。

# SUPER 数据类型和实体化视图
<a name="r_SUPER_MV"></a>

通过 Amazon Redshift，可以使用实体化视图来增强针对 SUPER 数据类型运行的查询的性能和灵活性。通过 SUPER 数据类型，可以在实体化视图中存储基表中列的超集，这样就可以直接查询实体化视图，而无需联接基表。以下各节将向您介绍如何在 Amazon Redshift 中使用 SUPER 数据类型创建和使用实体化视图。

Amazon Redshift 支持包含 SUPER 数据类型列和 PartiQL 查询的实体化视图。实体化视图可以递增刷新，而 Amazon Redshift 仅更新自上次刷新操作以来基表中发生更改的数据。这种选择性更新方法使刷新过程比完全重新计算更高效。有关实体化视图的更多信息，请参阅[Amazon Redshift 中的实体化视图](materialized-view-overview.md)。

## 加快 PartiQL 查询
<a name="r_accelerate_mv"></a>

您可以使用实体化视图加快在 SUPER 列中导航和/或取消嵌套分层数据的 PartiQL 查询。通过创建一个或多个实体化视图来将 SUPER 值分解为多个列，并利用 Amazon Redshift 分析查询的列式组织，您基本上可以提取和规范化嵌套数据。标准化程度取决于您在将 SUPER 数据转换为传统的柱状数据方面投入了多少精力。

以下主题展示了将复杂的数据分解或粉碎为较小列的示例，以及从分解的数据中创建标量列以提高性能的示例。

**Topics**
+ [加快 PartiQL 查询](#r_accelerate_mv)
+ [使用实体化视图将半结构化数据分解成 SUPER 列](r_shred_super.md)
+ [使用分解数据创建 Amazon Redshift 标量列](r_create_scalar.md)

# 使用实体化视图将半结构化数据分解成 SUPER 列
<a name="r_shred_super"></a>

通过 Amazon Redshift，可以使用实体化视图将数据分解为 SUPER 列，从而提高查询性能。分解指的是将半结构化 JSON 或 XML 等复杂数据类型分解成更小、更扁平的列的过程。SUPER 列是一种专门的列式存储形式，专为快速扫描已分解数据而优化。

以下各节将介绍在 Amazon Redshift 中使用实体化视图将数据分解成 SUPER 列的步骤和注意事项。

以下示例显示了一个实体化视图定义，用于将嵌套数据分解，其结果列仍为 SUPER 数据类型。

```
SELECT c.c_name, o.o_orderstatus
FROM customer_orders_lineitem c, c.c_orders o;
```

以下示例显示了一个实体化视图定义，用于通过分解的数据来创建传统的 Amazon Redshift 标量列。

```
SELECT c.c_name, c.c_orders[0].o_totalprice
FROM customer_orders_lineitem c;
```

您可以创建单个实体化视图 super\$1mv 来加速这两个查询。

要应答第一个查询，必须具体化属性 o\$1orderstatus。您可以省略属性 c\$1name，因为它不涉及嵌套导航或取消嵌套。您还必须在实体化视图中包括 customer\$1orders\$1lineitem 的属性 c\$1custkey，以便能够将基表与实体化视图联接起来。

要应答第二个查询，您还必须具体化属性 o\$1totalprice 和数组 index o\$1idx of c\$1orders。因此，您可以访问 c\$1orders 的索引 0。

```
CREATE MATERIALIZED VIEW super_mv distkey(c_custkey) sortkey(c_custkey) AS (
  SELECT c_custkey, o.o_orderstatus, o.o_totalprice, o_idx
  FROM customer_orders_lineitem c, c.c_orders o AT o_idx
);
```

实体化视图 super\$1mv are SUPER 的属性 o\$1orderstatus 和 o\$1totalprice。

对基表 customer\$1orders\$1lineitem 进行更改时，将以增量方式刷新实体化视图 super\$1mv。

```
REFRESH MATERIALIZED VIEW super_mv;
INFO: Materialized view super_mv was incrementally updated successfully.
```

若要将第一个 PartiQL 查询重写为常规 SQL 查询，请如下所示将 customer\$1orders\$1lineitem 与 super\$1mv as 联接。

```
SELECT c.c_name, v.o_orderstatus
FROM customer_orders_lineitem c 
JOIN super_mv v ON c.c_custkey = v.c_custkey;
```

同样，您可以重写第二个 PartiQL 查询。以下示例对 o\$1idx = 0 使用筛选条件。

```
SELECT c.c_name, v.o_totalprice
FROM customer_orders_lineitem c 
JOIN super_mv v ON c.c_custkey = v.c_custkey
WHERE v.o_idx = 0;
```

在 CREATE MATERIALIZED VIEW 命令中，将 c\$1custkey 指定为分配键，并为排序键指定 super\$1mv。Amazon Redshift 会执行高效的合并联接，假设 c\$1custkey 也是 customer\$1orders\$1lineitem 的分配键和排序键。如果不是这种情况，您可以指定 c\$1custkey 作为 customer\$1orders\$1lineitem 的排序键和分配键，如下所示。

```
ALTER TABLE customer_orders_lineitem
ALTER DISTKEY c_custkey, ALTER SORTKEY (c_custkey);
```

使用 EXPLAIN 语句验证 Amazon Redshift 是否对重写的查询执行合并联接。

```
EXPLAIN
      SELECT c.c_name, v.o_orderstatus
      FROM customer_orders_lineitem c JOIN super_mv v ON c.c_custkey = v.c_custkey;
      
      QUERY PLAN                                              
      ------------------------------------------------------------------------------------------------------
      XN Merge Join DS_DIST_NONE  (cost=0.00..34701.82 rows=1470776 width=27)
      Merge Cond: ("outer".c_custkey = "inner".c_custkey)
      ->  XN Seq Scan on mv_tbl__super_mv__0 derived_table2  (cost=0.00..14999.86 rows=1499986 width=13)
      ->  XN Seq Scan on customer_orders_lineitem c  (cost=0.00..999.96 rows=99996 width=30)
      (4 rows)
```

# 使用分解数据创建 Amazon Redshift 标量列
<a name="r_create_scalar"></a>

了解存储到 SUPER 中的无 schema 数据会影响 Amazon Redshift 的性能。例如，筛选条件谓词或联接条件作为范围限制扫描无法有效地使用区域映射。用户和 BI 工具可以使用实体化视图作为数据的传统表示形式，并提高分析查询的性能。

以下查询扫描实体化视图 `super_mv` 并筛选 `o_orderstatus`。

```
SELECT c.c_name, v.o_totalprice
FROM customer_orders_lineitem c
JOIN super_mv v ON c.c_custkey = v.c_custkey
WHERE v.o_orderstatus = 'F';
```

检查 `stl_scan` 以验证 Amazon Redshift 无法通过 `o_orderstatus` 在范围限制扫描中有效地使用区域映射。

```
SELECT slice, is_rrscan FROM stl_scan
WHERE query = pg_last_query_id() AND perm_table_name LIKE '%super_mv%';

 slice | is_rrscan 
-------+-----------
     0 | f
     1 | f
     5 | f
     4 | f
     2 | f
     3 | f
(6 rows)
```

以下示例调整实体化视图 `super_mv` 以从分解的数据中创建标量列。在这种情况下，Amazon Redshift 会将 `o_orderstatus` 从 SUPER 转换为 VARCHAR。此外，指定 `o_orderstatus` 作为 `super_mv` 的排序键。

```
CREATE MATERIALIZED VIEW super_mv distkey(c_custkey) sortkey(c_custkey, o_orderstatus) AS (
  SELECT c_custkey, o.o_orderstatus::VARCHAR AS o_orderstatus, o.o_totalprice, o_idx
  FROM customer_orders_lineitem c, c.c_orders o AT o_idx
);
```

重新运行查询后，验证 Amazon Redshift 现在可以使用区域映射。

```
SELECT v.o_totalprice
FROM super_mv v
WHERE v.o_orderstatus = 'F';
```

您可以验证范围限制扫描现在是否使用区域映射，如下所示。

```
SELECT slice, is_rrscan FROM stl_scan
WHERE query = pg_last_query_id() AND perm_table_name LIKE '%super_mv%';

 slice | is_rrscan 
-------+-----------
     0 | t
     1 | t
     2 | t
     3 | t
     4 | t
     5 | t
(6 rows)
```