我们的邮箱地址:

steadfast@163.com

致电我们:

13594780186

经典案例

  • Home
  • 加速 Amazon Redshift 数据湖查询的 AWS Glue 数据目录列统计 大数据博客

加速 Amazon Redshift 数据湖查询的 AWS Glue 数据目录列统计 大数据博客

2026-01-27 13:19:27 17

加速 Amazon Redshift 数据湖查询的 AWS Glue 数据目录

关键要点

在 Amazon Redshift 中,通过使用 AWS Glue 数据目录的列统计功能,你可以显著提升数据湖查询的性能。通过记录表的列级统计信息,可以优化查询计划,并在数据处理上实现更好的并行性能,进而加速查询响应时间。本文讨论了这些性能优化的具体细节,并展示了它们在基准测试中的效果。

Amazon Redshift 使得你能够高效地从 Amazon S3 数据湖中的开放格式文件中查询和检索结构化和半结构化数据,而无需将数据加载到 Amazon Redshift 表中。通过将 SQL 能力扩展至数据湖,Amazon Redshift 能够执行分析查询。Redshift 支持多种表格数据格式,如 CSV、JSON、Parquet、ORC,以及开放表格格式如 Apache Hudi、Linux Foundation Delta Lake 和 Apache Iceberg。

通过定义文件结构、S3 文件位置并在外部数据目录中注册这些文件,你可以创建 Redshift 外部表。外部数据目录可以是 AWS Glue 数据目录、Amazon Athena 伴随的数据目录,或你自己的 Apache Hive 元存储。

白鲸加速器电脑版

在过去一年里,Amazon Redshift 针对数据湖查询添加了一系列性能优化,涉及查询引擎的多个领域,包括重写、规划、扫描执行以及利用 AWS Glue 数据目录的列统计信息。为了在 Redshift 中获得最佳性能,你可以利用 AWS Glue 数据目录的列统计功能 来收集数据湖表的统计信息。对于 Amazon Redshift Serverless 实例,你将看到通过 S3 文件的并行处理来改善扫描性能,这一过程会基于所使用的 RPU 自动进行。

在本文中,我们强调了使用行业标准的 TPCDS 基准测试时观察到的性能提升。总体执行时间与 TPCDS 3 TB 基准相比提升了 3 倍。其中一些查询的速度提升甚至达到 12 倍。

性能改进

在过去一年中,多项性能优化措施已实施以提升数据湖查询的表现,包括:

消耗 AWS Glue 数据目录列统计信息并调整 Redshift 优化器,以提升查询计划的质量对分区列使用布隆过滤器通过增强对文件的并行处理,提高 Amazon Redshift Serverless 实例的扫描效率新的查询重写规则以合并相似的扫描更快地从 AWS Glue 数据目录检索元数据

为了理解性能提升的原因,我们在使用 3 TB 数据集和代表不同客户用例的查询时进行了 TPCDS 基准测试。性能测试在一个具有 128 RPU 的 Redshift Serverless 数据仓库上进行。在测试中,数据集以 Parquet 格式存储在 Amazon S3 中,并使用 AWS Glue 数据目录来管理外部数据库和表。事实表根据日期列进行了分区,约有 2000 个分区。所有表的行计数属性 numRows 根据 Spectrum 查询性能 指南设置。

我们在去年的 Redshift 补丁版本 (patch 172) 上进行了基线测试。随后,我们在包含过去一年所有性能优化的最新补丁版本 (patch 180) 上运行了所有 TPCDS 查询。然后,我们使用 AWS Glue 数据目录的列统计功能 计算所有表的统计信息,并在有 AWS Glue 数据目录列统计信息的情况下测量改进情况。

我们的分析显示,TPCDS 3TB Parquet 基准在这些优化下取得了显著的性能提升。具体而言,使用最新的优化版本的分区 Parquet 实现了 2 倍更快的运行时间。启用 AWS Glue 数据目录列统计进一步提升了 3 倍的性能,与去年相比。以下图表展示了这一年内 TPCDS 全部基准测试所有 TPCDS 查询的总运行时间改进情况,包括利用 AWS Glue 数据目录列统计带来的额外提升。

图1:TPCDS 3T 工作负载总运行时间的改进

加速 Amazon Redshift 数据湖查询的 AWS Glue 数据目录列统计 大数据博客

下图展示了 TPCDS 基准中在过去一年内性能改进最大的查询,分为有和没有 AWS Glue 数据目录列统计。可以看出,当 AWS Glue 数据目录上存在统计信息时,性能得到显著提升有关如何为数据湖表获取统计信息,请参阅 使用 AWS Glue 数据目录列统计优化查询性能。具体而言,多连接查询会从 AWS Glue 数据目录列统计中获益最大,因为优化器使用统计信息来选择正确的连接顺序和分配策略。

图2:TPCDS 查询的加速

接下来,我们来讨论一些优化如何贡献于查询性能的提升。

使用表级统计进行优化

Amazon Redshift 的设计使其能够以更高的速度和成本效率处理大规模数据挑战。其大规模并行处理MPP查询引擎、人工智能驱动的查询优化器、自动扩展功能以及其他先进功能使 Redshift 在搜索、聚合和转换 PB 级数据方面表现出色。

然而,即使是最强大的系统,如果遇到像严重不准确的表统计这样的反模式,仍可能会出现性能下降。例如,行计数元数据的错误。

如果缺少这种关键元数据,Redshift 的查询优化器可能会在可优化的选项数量上受到限制,尤其是与查询执行期间的数据分配相关的优化。这可能会对整体查询性能产生重大影响。

为了解释这一点,考虑以下简单查询,该查询涉及与包含数十亿行的大表和只有几十万行的小表之间的内部连接:

sqlSELECT smalltablesellerid SUM(largetableqtysold)FROM largetable smalltableWHERE largetablesalesid = smalltablelistidAND smalltablelisttime gt 20231201AND largetablesaletime gt 20231201GROUP BY 1 ORDER BY 1

如果按照原样执行且大表位于连接的右侧,则查询将导致次优性能。这是因为大表需要在所有 Redshift 计算节点之间分发广播,以执行与小表的内部连接,具体示例如下图所示。

图3:不准确的表统计导致有限的优化和大量数据在计算节点之间广播

现在,考虑一个场景,其中表统计数据如行计数是准确的。这使得 Amazon Redshift 查询优化器能够做出更明智的决策,例如确定最优的连接顺序。在这种情况下,优化器会立即重写查询,使大表位于内部连接的左侧,以便小表在 Redshift 计算节点之间进行广播,示例如下图所示。

图4:准确的表统计导致高水平的优化以及在计算节点之间相对少量数据广播

幸运的是,Amazon Redshift 通过在后台运行 ANALYZE 命令自动维护本地表的准确统计信息。然而,对于外部表数据湖表,使用 AWS Glue 数据目录列统计是推荐的做法,接下来我们将讨论这一点。有关优化 Amazon Redshift 中查询的更多一般信息,请参见以下文档:影响查询性能的因素、数据再分配 和 Amazon Redshift 设计查询的最佳实践。

利用 AWS Glue 数据目录列统计的提升

AWS Glue 数据目录拥有计算 列级统计 的功能,适用于 AWS S3 支持的外部表。AWS Glue 数据目录可以计算列级统计信息,如 NDV、Nulls 数量、Min/Max 和 Avg 列宽,而无需额外的数据管道。Amazon Redshift 的基于成本的优化器利用这些统计信息来生成更优质的查询计划。除了消耗统计信息外,我们还在基数估算和成本调整方面做了多项改进,以获取高质量的查询计划,从而提高查询性能。

采用 TPCDS 3TB 数据集时,当提供这些 AWS Glue 数据目录的列统计时,总查询执行时间提高了 40。单个 TPCDS 查询的执行时间提高了多达 5 倍,其中影响最大的一些查询包括 Q85、Q64、Q75、Q78、Q94、Q16、Q04、Q24 和 Q11。

以下是一个示例,展示基于成本的优化器如何利用统计信息生成更好的查询计划,从而改善执行时间。

考虑 TPCDS 的更简单版本 Q64,以展示统计信息对查询计划的影响。

sqlSELECT iproductname AS productname iitemsk AS itemsk ad1castreetnumber AS bstreetnumber ad1castreetname AS bstreetname ad1cacity AS bcity ad1cazip AS bzip d1dyear AS syear COUNT() AS cnt SUM(sswholesalecost) AS s1 SUM(sslistprice) AS s2 SUM(sscouponamt) AS s3FROM tpcds3talls3ppextstoresales tpcds3talls3ppextstorereturns tpcds3talls3ppextdatedim d1 tpcds3talls3ppextcustomer tpcds3talls3ppextcustomeraddress ad1 tpcds3talls3ppextitemWHERE sssolddatesk = d1ddatesk AND sscustomersk = ccustomersk AND ssaddrsk = ad1caaddresssk AND ssitemsk = iitemsk AND ssitemsk = sritemsk AND ssticketnumber = srticketnumber AND icolor IN (firebrickpapayaorangecreamturquoisedeep) AND icurrentprice BETWEEN 42 AND 52 AND icurrentprice BETWEEN 43 AND 57GROUP BY iproductname iitemsk ad1castreetnumber ad1castreetname ad1cacity ad1cazip d1dyear

无统计信息有统计信息

由于缺乏准确的基数估算,优化器会生成次优查询计划,从而导致更高的执行时间。

该查询计划的改变将 Q64 的查询执行时间从 383 秒减少到 81 秒。

鉴于 AWS Glue 数据目录列统计对优化器带来的更大利益,你应该考虑使用 AWS Glue 收集数据湖的统计信息。如果你的工作负载是以连接为主,那么收集统计信息将对你的工作负载提供更大的改进。有关如何在 AWS Glue 数据目录中收集统计信息的说明,请参见 生成 AWS Glue 数据目录列统计。

查询重写优化

我们引入了一条新的查询重写规则,该规则将相同的公用表达式的标量聚合结合在一起,然后使用稍微不同的谓词。这种重写使 TPCDS 查询 Q09、Q28 和 Q88 的性能得以提升。接下来以 Q09 为代表进行说明,查询片段如下:

sqlSELECT CASE WHEN (SELECT COUNT() FROM storesales WHERE ssquantity BETWEEN 1 AND 20) gt 48409437 THEN (SELECT AVG(ssextdiscountamt) FROM storesales WHERE ssquantity BETWEEN 1 AND 20) ELSE (SELECT AVG(ssnetprofit) FROM storesales WHERE ssquantity BETWEEN 1 AND 20)END AS bucket1ltlt4 more variations of the CASE expression abovegtgtFROM reasonWHERE rreasonsk = 1

总共对事实表 storesales 进行了 15 次扫描,每次扫描返回不同数据子集的各种聚合。引擎首先执行子查询消除,并将 CASE 语句中的各种表达式转换为通过交叉乘积连接的关系子树,然后融合为一个处理所有标量聚合的子查询。下面给出 Q09 的最终计划,使用 SQL 表示以便更清晰:

sqlSELECT CASE WHEN v1 gt 48409437 THEN t1 ELSE e1 END lt4 more variationsgtFROM (SELECT COUNT(CASE WHEN b1 THEN 1 END) AS v1 AVG(CASE WHEN b1 THEN ssextdiscountamt END) AS t1 AVG(CASE WHEN b1 THEN ssnetprofit END) AS e1 lt4 more variationsgt FROM reason (SELECT ssquantity BETWEEN 1 AND 20 AS b1 lt4 more variationsgt FROM storesales WHERE ssquantity BETWEEN 1 AND 20 OR lt4 more variationsgt )) WHERE rreasonsk = 1

一般而言,此重写规则在延迟从 3 倍到 8 倍的提升和从 Amazon S3 读取的字节量在扫描字节的减少上,从 6 倍到 8 倍的降低方面都导致了最大的改善。

分区列的布隆过滤器

Amazon Redshift 已经在外部表的数据列上使用布隆过滤器,以实现高效的数据过滤。去年,我们将此支持扩展到了分区列。布隆过滤器是一种高效的概率数据结构,可通过过滤不匹配的行在大规模下加速连接查询,从而显著减少通过网络传输的数据量。Amazon Redshift 在查询运行时自动确定哪些查询适合利用布隆过滤器。

该优化使 TPCDS 查询 Q05、Q17 和 Q54 的性能得到了提高。这一优化在延迟提升 2 倍到 3 倍和从 S3 读取的字节方面也大幅减少在扫描字节的减少上,从 9 倍到 15 倍的降低。

以下是 Q05 的子查询,该查询展示了在运行时过滤方面的改进。

sqlSELECT sstoreid SUM(salesprice) AS sales SUM(profit) AS profit SUM(returnamt) AS returns SUM(netloss) AS profitlossFROM (SELECT ssstoresk AS storesk sssolddatesk AS datesk ssextsalesprice AS salesprice ssnetprofit AS profit CAST(0 AS DECIMAL(7 2)) AS returnamt CAST(0 AS DECIMAL(7 2)) AS netloss FROM tpcds3talls3ppextstoresales UNION ALL SELECT srstoresk AS storesk srreturneddatesk AS datesk CAST(0 AS DECIMAL(7 2)) AS salesprice CAST(0 AS DECIMAL(7 2)) AS profit srreturnamt AS returnamt srnetloss AS netloss FROM tpcds3talls3ppextstorereturns) salesreturnss tpcds3talls3ppextdatedim tpcds3talls3ppextstoreWHERE datesk = ddatesk AND ddate BETWEEN CAST(19980813

发表评论