sql - 如何最有效地比较 Amazon Athena 中的日期组件?
问题描述
我有两个几乎相同的表,具有以下架构,包含帐号、值和日期,分为 3 个值,但格式不同。每个帐户/天可以有很多行。我正在使用亚马逊雅典娜。
CREATE TABLE tableA (
accnt_num string, --ex: 8923747897423
value1 int,
partition_0 string, --ex: 2021
partition_1 string, --ex: 01
partition_2 string, --ex: 07
);
CREATE TABLE tableB (
accnt_num string, --ex: 8923747897423
value2 int,
partition_0 string, --ex: 2021
partition_1 string, --ex: 1
partition_2 string, --ex: 7
);
我想在相同的分区上加入表(是的,帐号匹配也是加入的条件,但这很容易,因为它们具有相同的格式/数据类型,因此不是问题的焦点)。假设 > 10,000,000 行,最快的方法是什么?
SELECT * FROM tableA a
JOIN tableB b
on cast(a.partition_2 as int) = cast(b.partition_2 as int)
...
或者
任何其他种类的字符串操作(例如,如果第一个位置没有 0,则添加 0,如果另一个表的第一个位置存在 0,则修剪 0,等等...)
或者
首先将它们组合在一起,作为日期投射,然后与另一张表进行比较?
我希望它尽可能高效。
解决方案
我怀疑类型转换会产生很大的不同,其他事情会对性能产生更大的影响。
在像 Athena 这样的分布式引擎中,网络开销将主导查询的运行时间。CPU 绑定处理的重要性将超过一个数量级或数量级。
在 Athena 中优化连接的一般建议是按大小顺序列出表,最大的在前。如果您的一张桌子较小,确保它不是第一张桌子会有很大的不同。
之后,您必须确保 Athena 能够正确修剪分区。使用EXPLAIN
和totalBytesScanned
统计信息来确保 Athena 没有读取太多数据(例如,我不知道 Athena 是否足够聪明,可以正确修剪 中的两个表上的分区SELECT * FROM t1 LEFT JOIN t2 ON (t1.partition0 = t2.partition0) WHERE t1.partition0 = 'xyz'
,例如,您可能需要添加AND t2.partition0 = 'xyz'
)。
一旦你确定你已经优化了尽可能多的网络开销,你可以简单地运行带有强制转换和没有强制转换的查询,看看是否有任何可测量的差异,但我怀疑你是否能够观察到任何差异。
推荐阅读
- asp.net-mvc - Google Authenticator ValidateTwoFactorPIN(UserUniqueKey, token) 总是假 MVC 5
- react-native - 从反应原生的TextInput获取值时,错误未定义不是对象
- mysql - 当 mysql 将事务 id 分配给事务时
- python - 在数据集中保留前 n 个模式项(timeserie)
- ruby-on-rails - 如何使用列数组获取对象的值?
- python - 不断地读取一个文件最终会损坏我的硬盘吗?
- r - 将 DTedit 与“新行”ActionButton 集成
- actionscript-3 - 调用函数时是否可以忽略变量?(动作脚本3)
- ios - 如何访问传入推送通知的值
- flutter - 如何知道 ListView 在最初呈现时是否溢出屏幕?