我在Amazon Athena(Presto引擎(中有一个表,其中包含一些用户事件,其中包括userId(VARCHAR(和ts(timestamp,BIGINT(列。桌子很大,有上亿张唱片。我想创建一个按ts列对事件进行排序的查询。我很快发现我不能使用全局ORDER BY ts
,因为这意味着所有ts值都应该存储在单个工作节点的内存中,这会导致内存不足类型错误。
关键是,实际上我不需要全局地对这些事件进行排序,如果对单个用户ID进行排序就足够了。我还试图使用一个复合查询,其中外部查询获得所有唯一的userid,内部查询使用WHERE userid = current_userid
子句,但由于我有大约5万个不同的userid——这个查询运行的时间太长了。(JOIN
将查询结果组合在一起也是如此(。我正在寻找一些只使用部分行排序的sql构造,比如ORDER BY ts OVER (PARTITION BY userid)
(此子句无效(。
我很快发现我不能使用全局ORDER BY ts,因为这意味着所有ts值都应该存储在单个工作节点的内存中,这会导致内存不足类型的错误
Presto支持分布式排序已经一年多了(由Starburst贡献(。分布式排序消除了将所有数据放在一个节点内存中的需要,从而允许对排序操作进行线性缩放。节点越多,可以排序的数据就越多,而不会影响任何性能(不涉及磁盘/存储(。
我不认为有一种方法可以强制旧的Presto版本在不将所有数据放入一个节点的内存的情况下有效地进行总排序。因此,除非Athena本身支持分布式排序,否则您无法在用户端进行补偿。
您可以从获得最新的Presto版本https://trino.io/download.html
由于您在AWS上,您可以使用Starburst Presto for AWS在亚马逊上进行一键(好吧,实际上是"几次点击"(部署。(我来自星爆(。
您似乎在寻找:
ORDER BY RANK() OVER (PARTITION BY userid ORDER BY ts)
然而,我不确定这是否真的会限制你们工人的内存消耗。你需要测试一下。