Athena 引擎版本 2
Athena 引擎版本 2 引入了以下更改。目前,Athena 引擎版本 2 在所有支持 Athena 的区域中可用,包括非洲(开普敦)、亚太地区(香港)、亚太地区(孟买)、亚太地区(大阪)、亚太地区(首尔)、亚太地区(新加坡)、亚太地区(悉尼)、亚太地区(东京)、Amazon GovCloud(美国东部)、Amazon GovCloud(美国西部)、加拿大(中部)、中国(北京)、中国(宁夏)、欧洲(法兰克福)、欧洲(爱尔兰)、欧洲(伦敦)、欧洲(米兰)、欧洲(巴黎)、欧洲(斯德哥尔摩)、中东(巴林)、南美洲(圣保罗)、美国东部(弗吉尼亚北部)、美国东部(俄亥俄)、美国西部(加利福尼亚北部)、美国西部(俄勒冈)。
改进功能和新功能
-
EXPLAIN 和 EXPLAIN ANALYZE – 您可以使用 Athena 中的
EXPLAIN
语句查看 SQL 查询的执行计划。使用EXPLAIN ANALYZE
查看 SQL 查询的分布式执行计划以及每项操作的成本。有关更多信息,请参阅在 Athena 中使用 EXPLAIN 和 EXPLAIN ANALYZE。 -
联合查询 – Athena 引擎版本 2 支持联合查询。有关更多信息,请参阅使用 Amazon Athena 联合查询。
-
地理空间函数 – 添加了超过 25 个地理空间函数。有关更多信息,请参阅Athena 引擎版本 2 中新增的地理空间函数。
-
嵌套架构 – 添加了对读取嵌套架构的支持,从而降低了成本。
-
预编译语句 – 使用预编译语句重复执行具有不同查询参数的同一查询。预编译语句包含占位符参数,其值在运行时传递。预编译语句有助于防止 SQL 注入攻击。有关更多信息,请参阅使用参数化查询。
-
架构演变支持 – 添加了 Parquet 格式数据的架构演进支持。
-
添加了对从分区架构与表架构不同的分区读取数组、映射或行类型列的支持。创建分区后,更新表架构时可能会发生这种情况。更改后的列类型必须兼容。对于行类型,可以添加或删除尾随字段,但相应字段(按顺序)必须具有相同的名称。
-
ORC 文件现在可以具有缺少字段的结构列。这可在不重写 ORC 文件的情况下更改表架构。
-
ORC 结构列现在是按名称而不是顺序映射的。这可以正确处理 ORC 文件中缺少或多出的结构字段。
-
-
SQL OFFSET –
SELECT
语句现在支持 SQLOFFSET
子句。有关更多信息,请参阅SELECT。 -
UNLOAD 语句 – 您可以使用
UNLOAD
语句将SELECT
查询的输出以 PARQUET、ORC、AVRO 和 JSON 格式写入。有关更多信息,请参阅UNLOAD。
分组、联接和子查询改进
-
复杂分组 – 增加了对复杂分组操作的支持。
-
关联的子查询 – 添加了对
IN
谓词中相关子查询和需要强制转换的相关子查询的支持。 -
CROSS JOIN – 添加了针对
LATERAL
的派生表对CROSS JOIN
的支持。 -
GROUPING SET – 添加了对使用
GROUPING SETS
的查询以聚合的形式对ORDER BY
子句的支持。 -
Lambda 表达式 – 添加了对在 Lambda 表达式中取消引用行字段的支持。
-
半连接中的空值 – 添加了对半连接左侧空值的支持(即带有
IN
谓词的子查询)。 -
空间联接 – 添加了对广播空间连接和空间左连接的支持。
-
溢出到磁盘 – 对于内存密集型
INNER JOIN
和LEFT JOIN
操作,Athena 会将中间操作结果卸载到磁盘中。这样可以执行需要大量内存的查询。
数据类型增强功能
-
INT for INTEGER – 添加了对
INT
的支持,作为INTEGER
数据的别名。 -
INTERVAL 类型 – 添加了对
INTERVAL
类型的转换支持。 -
IPADDRESS – 添加了一个新的
IPADDRESS
类型来表示 IP 地址。增加了对在VARBINARY
类型和IPADDRESS
类型之间的转换。 -
IS DISTINCT FROM – 添加了对于
JSON
和IPADDRESS
类型的IS DISTINCT FROM
支持。 -
空值等效性检查 –
ARRAY
、MAP
, 和ROW
数据结构中的空值等效性检查现已得到支持。例如,表达式ARRAY ['1', '3', null] = ARRAY ['1', '2', null]
返回false
。以前,空元素会返回错误消息comparison not supported
(不支持比较)。 -
行类型强制转换– 现在允许在行类型之间进行强制操作,而不考虑字段名称。以前,只有当源类型中的字段名与目标类型匹配时,或者当目标类型具有匿名字段名称时,才可强制转换为另一行类型。
-
时间减法 – 为所有
TIME
和TIMESTAMP
类型执行减法。 -
Unicode – 在字符串文字中添加了对转义 Unicode 序列的支持。
-
VARBINARY 连接 – 添加了对
VARBINARY
值连接的支持。窗口值函数 – 窗口值函数现在支持
IGNORE NULLS
和RESPECT NULLS
。
函数的其他输入类型
以下函数现在接受其他输入类型。有关各个函数的更多信息,请访问 Presto 文档的相应链接。
-
approx_distinct() – approx_distinct()
函数现在支持以下类型: INTEGER
、SMALLINT
、TINYINT
、DECIMAL
、REAL
、DATE
、TIMESTAMP
、TIMESTAMP WITH TIME ZONE
、TIME
、TIME WITH TIME ZONE
、IPADDRESS
和CHAR
。 -
Min()、max() – min()
和 max() 聚合函数现在允许在查询分析时使用未知的输入类型,以便您可以将函数用于 NULL
文本。 -
regexp_replace() – 添加了 regexp_replace()
函数的变体,可以为每个替换执行 Lambda 函数。 -
Sequence() – 已将
DATE
变体添加到 sequence()函数,包括带有隐式一天步骤增量的变体。 -
ST_Area() – ST_Area()
地理空间函数现在支持所有几何类型。 -
Substr() – substr
函数现在可以执行 VARBINARY
输入。 -
zip_with() – 长度不匹配的数组现在可以与 zip_with()
共同使用。缺少的位置将用空值填充。以前,传递不同长度的数组时会引发错误。这种更改可能会使得难以区分最初为空的值和添加来填充相同长度数组的值。
已添加的函数
下面的列表包含在 Athena 引擎版本 2 中新启动的函数。该列表不包括地理空间函数。有关地理空间函数的列表,请参阅 Athena 引擎版本 2 中新增的地理空间函数。
有关各个函数的更多信息,请访问 Presto 文档的相应链接。
聚合函数
数组函数和运算符
array_sort()
二进制函数和运算符
日期与时间函数和运算符
映射函数和运算符
数学函数和运算符
分位数摘要函数
分位数摘要函数qdigest
分位数摘要类型已添加。
字符串函数和运算符
性能改进
在 Athena 引擎版本 2 中,以下功能的性能得到了改进。
查询性能
-
广播联接性能 – 通过在 Worker 节点中应用动态分区修剪来提高广播联接性能。
-
分桶表 – 在正在写入的数据已经适当分区(例如,当输出来自分桶连接时)时,改进了写入分桶表的性能。
-
DISTINCT – 改进了一些使用
DISTINCT
的查询的性能。动态筛选和分区修剪 – 改进提高了性能,减少了查询中扫描的数据量。
-
筛选条件和投影操作 – 筛选条件和投影操作现在始终由列处理(如可能)。引擎在有效的情况下将自动采用字典编码。
-
收集交换 – 改进了通过收集交换查询的性能。
-
全局聚合 – 改进了执行筛选全局聚合的某些查询的性能。
-
GROUPING SETS, CUBE, ROLLUP – 改进了涉及您可以用来在单个查询中聚合多组列的
GROUPING SETS
、CUBE
或者ROLLUP
的查询性能。 -
高度选择性的筛选条件 – 改进了具有高度选择性筛选条件的查询的性能。
-
JOIN 和 AGGREGATE 操作 –
JOIN
和AGGREGATE
操作的性能得到了增强。 -
LIKE – 改进了在
information_schema
表的列上使用LIKE
谓词的查询性能。 -
ORDER BY 和 LIMIT – 改进了涉及
ORDER BY
和LIMIT
的查询的计划、性能和内存使用情况,以避免不必要的数据交换。 -
ORDER BY –
ORDER BY
操作现在默认分布,从而能够使用更大ORDER BY
子句。 -
ROW 类型转换 – 改进了在
ROW
类型之间转换时的性能。 -
结构类型 – 改进了处理结构类型并包含扫描、连接、聚合或表写入的查询的性能。
-
表扫描 – 引入了优化规则,以避免在某些情况下重复表扫描。
-
UNION – 改进了
UNION
查询的性能。
查询计划性能
-
规划性能 – 改进了联接多个包含大量列的表的查询规划性能。
-
谓词评估 – 改进了规划中谓词下推期间的谓词评估性能。
-
转换的谓词下推支持 – 当值列表中的值要求进行转换以匹配列类型时,支持对
<column>
IN
<values list>
谓词的谓词下推。 -
谓词推理和下推 – 为使用
<symbol>
IN
<subquery>
谓词的查询扩展了谓词推理和下推。 -
超时 – 修复了在极少数情况下可能导致查询计划超时的错误。
联接性能
-
使用映射列连接 – 改进了包含映射列的连接和聚合的性能。
-
单独使用非相等条件连接 – 通过使用嵌套循环连接而不是散列连接来改进仅具有非相等条件的连接的性能。
-
外部联接 – 对于涉及外连接的查询,现在会自动选择连接分配类型。
-
函数连接范围 – 改进了连接的性能,其中条件是函数的范围(例如
a JOIN b ON b.x < f(a.x) AND b.x > g(a.x)
)。 -
溢出到磁盘 – 修复了与溢出到磁盘相关的错误和内存问题,以提高性能并减少
JOIN
操作中的内存错误。
子查询性能
-
关联的 EXISTS 子查询 – 改进了关联的
EXISTS
子查询性能。 -
带有相等谓词的关联子查询 – 改进了对包含相等谓词的关联子查询的支持。
-
带有不等谓词的关联子查询 – 改进了包含不等谓词的关联子查询的性能。
-
子查询上的 count(*) 聚合 – 改进了具有已知常量基数的子查询的
count(*)
聚合性能。 -
外部查询筛选条件传播 – 在外部查询的筛选条件可以传播到子查询时,改进了相关子查询的性能。
函数性能
-
聚合窗口函数 – 改进了聚合窗口函数的性能。
-
element_at() – 为映射改进了
element_at()
的性能,使其成为恒定时间,而非与地图大小成正比。 -
Grouping() – 改进了涉及
grouping()
的查询的性能。 -
JSON 转换 – 改进了从
JSON
转换到ARRAY
或MAP
类型的性能。 -
映射返回函数 – 改进了返回映射的函数性能。
-
映射到映射转换 – 改进了映射到映射转换的性能。
-
Min() 和 max() –
min()
和max()
函数已经过优化,以避免不必要的对象创建,从而减少垃圾回收开销。 -
row_number() – 改进了使用
row_number()
并生成了行号筛选条件的查询性能和内存使用情况。 -
窗口函数 – 改进了包含具有相同
PARTITION BY
和ORDER BY
子句的窗口函数的查询性能。 -
窗口函数 – 改进了某些具有类似规格窗口函数(例如
LAG
)的性能。
地理空间性能
-
几何体序列化 – 改进了几何体值的序列化性能。
-
地理空间函数 – 改进了
ST_Intersects()
、ST_Contains()
、ST_Touches()
、ST_Within()
、ST_Overlaps()
、ST_Disjoint()
、transform_values()
、ST_XMin()
、ST_XMax()
、ST_YMin()
、ST_YMax()
、ST_Crosses()
和array_intersect()
的性能。 -
ST_Distance() – 改进了涉及
ST_Distance()
函数的连接查询的性能。 -
ST_Intersection() – 为与坐标轴对齐的矩形优化了
ST_Intersection()
函数(例如,ST_Envelope()
和bing_tile_polygon()
函数生成的多边形)。
JSON 相关改进
映射函数
-
改进了所有案例中从
O(n)
到O(1)
映射下标的性能。以前,只有某些函数和读取器生成的映射才能利用这一改进。 -
增加了
map_from_entries()
和map_entries()
函数。
转换
-
增加了从
REAL
、TINYINT
或SMALLINT
转换到JSON
的能力。 -
现在,您可以将
JSON
转换为ROW
,即使JSON
不包含ROW
中的所有字段。 -
提高了
CAST(json_parse(...) AS ...)
的性能。 -
改进了从
JSON
转换到ARRAY
或者MAP
类型的性能。
新 JSON 函数
重大更改
突破性更改包括错误修复、对地理空间函数的更改、替换函数以及引入限制。ANSI SQL 合规性的改进可能会中断依赖于非标准行为的查询。
错误修复
以下更改修正了导致查询成功运行但结果不准确的行为问题。
-
fixed_len_byte_array Parquet 列现在被接受为 DECIMAL – 如果查询在 Parquet Schema 中被注释为
DECIMAL
,则对fixed_len_byte_array
类型的 Parquet 列的查询成功并返回正确的值。不含DECIMAL
注释的fixed_len_byte_array
列查询将失败,并出现错误。以往,没有 DECIMAL 注释的fixed_len_byte_array
列查询将会成功,但会返回令人难以理解的值。 -
json_parse() 不再忽略尾随字符 – 以往,诸如
[1,2]abc
等输入将成功解析为[1,2]
。使用尾随字符现在会生成错误消息Cannot convert '[1, 2]abc' to JSON
(无法将 '[1, 2]abc' 转换为 JSON)。 -
Round() 小数精度校正 – 若
x
是 DECIMAL,或x
是小数位数 0 的 DECIMAL,且d
是负整数,则round(x, d)
现在会正确舍入x
。以往,在这些情况下没有进行四舍五入。 -
round(x, d) 和 truncate(x, d) – 函数
round(x, d)
和truncate(x, d)
的签名中的参数d
现在的类型为INTEGER
。以往,d
的类型可能是BIGINT
。 -
带有重复键的 map() –
map()
现在会在重复键上引发错误,而不是静默地生成损坏的映射。当前使用重复键构建映射值的查询将会在失败时显示错误。 -
map_from_entries() 引发一个带有空条目的错误 –
map_from_entries()
现在会在输入数组包含空条目时引发错误。通过传递NULL
作为一个值来构建映射的查询现在将会失败。 -
表 – 不能再创建具有不受支持的分区类型的表。
-
改进统计函数的数值稳定性 – 统计函数
corr()
、covar_samp()
、regr_intercept()
和regr_slope()
的数值稳定性已改进。 -
Parquet 中定义的 TIMESTAMP 精度现将正确地实施 – Parquet 架构中
TIMESTAMP
值的精度以及为TIMESTAMP
列定义的精度现在必须匹配。不匹配的精度会导致不正确的时间戳。 -
时区信息 – 现在将使用 Java 1.8 软件开发工具包的 java.time
软件包计算时区信息。 -
INTERVAL_DAY_TO_SECOND 与 INTERVAL_YEAR_TO_MONTH 数据类型的 SUM – 您现在无法再直接使用
SUM(NULL)
。为了使用SUM(NULL)
,将NULL
强制转换为BIGINT
、DECIMAL
、REAL
、DOUBLE
、INTERVAL_DAY_TO_SECOND
或者INTERVAL_YEAR_TO_MONTH
等数据类型。
地理空间函数的更改
对地理空间函数所做的更改包括以下各项。
-
函数名更改 – 某些函数名称已更改。有关更多信息,请参阅Athena 引擎版本 2 中的地理空间函数名称更改。
-
VARBINARY 输入 –
VARBINARY
类型不再直接支持地理空间函数的输入。例如,要直接计算几何的面积,现在必须将几何体以VARCHAR
或者GEOMETRY
格式输入。解决方法是使用转换函数,如以下示例所示。-
要使用
ST_area()
以计算采用 Well-Known Binary (WKB) 格式的VARBINARY
输入的面积,请将输入传递给ST_GeomFromBinary()
,例如:ST_area(ST_GeomFromBinary(
<wkb_varbinary_value>
)) -
要使用
ST_area()
来计算采用传统二进制格式的VARBINARY
输入,请首先将相同的输入传递给ST_GeomFromLegacyBinary()
函数,例如:ST_area(ST_GeomFromLegacyBinary(
<legacy_varbinary_value>
))
-
-
ST_ExteriorRing() 和 ST_Polygon() – ST_ExteriorRing() 和 ST_Polygon() 现在仅接受多边形作为输入。以前,这些函数错误地接受了其他几何体。
-
ST_Distance() – 根据 SQL/MM 规范
的要求,如果其中一个输入为空几何体,则 ST_Distance() 函数现在会返回 NULL
。以往,将会返回NaN
。
ANSI SQL 合规性
以下语法和行为问题已得到更正,以遵循 ANSI SQL 标准。
-
Cast() 操作 – 从 REAL 或 DOUBLE 到 DECIMAL 的 Cast() 操作现在符合 SQL 标准。例如,
cast (double '100000000000000000000000000000000' as decimal(38))
以前返回100000000000000005366162204393472
但现在返回100000000000000000000000000000000
。 -
JOIN ... USING –
JOIN ... USING
现在符合标准 SQL 语义。以往,JOIN ... USING
需要限定列中的表名,而两个表中的列将出现在输出中。表限定现在无效,而列仅在输出中出现一次。 -
删除了 ROW 类型的文字 – ROW 类型的文字格式
ROW<int, int>(1, 2)
不再受支持。现在将使用语法ROW(1 int, 2 int)
。 -
Log() 函数 – 以往,如果违反了 SQL 标准,则
log()
函数中的参数顺序将被颠倒。这导致log()
会在查询被转换为其他 SQL 实现或从其他 SQL 实施实现转换时返回不正确的结果。log(x, b)
的等效函数现在为正确的ln(x) / ln(b)
。 -
分组聚合语义 – 分组聚合使用
IS NOT DISTINCT FROM
语义而不是等效语义。分组聚合现在会返回正确的结果,并在NaN
浮点数值进行分组时展现出更好的性能。现在支持对包含空值的映射、列表和行类型进行分组。 -
不再允许带引号的类型 – 根据 ANSI SQL 标准,数据类型不能再用引号括起来。例如,
SELECT "date" '2020-02-02'
不再是有效的查询。请改用语法SELECT date '2020-02-02'
。 -
匿名行字段访问 – 匿名行字段不能再使用语法 [
.field0, .field1, ...
] 访问。 -
复杂分组操作 – 复杂的分组操作
GROUPING SETS
、CUBE
和ROLLUP
不支持对由输入列组成的表达式进行分组。只允许使用列名。
替换函数
以下函数不再受支持,已由生成相同结果的语法替换。
-
information_schema.__internal_partitions__ – Athena 引擎版本 2 不再支持使用
__internal_partitions__
。如需等效的语法,请使用SELECT * FROM "
或者<table_name>
$partitions"SHOW PARTITIONS
。有关更多信息,请参阅列出特定表的分区。 -
替换的地理空间函数 – 有关名称已更改的地理空间函数的列表,请参阅 Athena 引擎版本 2 中的地理空间函数名称更改。
限制
Athena 引擎版本 2 中引入了以下限制,以确保查询不会因资源限制而失败。用户无法配置这些限制。
-
结果元素的数量 – 结果元素的数量
n
对于函数min(col, n)
、max(col, n)
、min_by(col1, col2, n)
和max_by(col1, col2, n)
将限制在 10,000 或更少。 -
GROUPING SETS – 分组集中的最大切片数为 2048。
-
最大文本文件行长度 – 文本文件的默认最大行长为 100 MB。
-
序列函数最大结果大小 – 序列函数的最大结果大小为 50000 个条目。例如,
SELECT sequence(0,45000,1)
成功,但SELECT sequence(0,55000,1)
会失败并显示错误消息The result of the sequence function must not have more than 50000 entries
(序列函数的结果不得超过 50000 个条目)。此限制适用于序列函数的所有输入类型,包括时间戳。