【问题标题】:how to do global sorting without a unique key in Presto如何在 Presto 中没有唯一键的情况下进行全局排序
【发布时间】:2022-01-06 22:56:39
【问题描述】:

就我而言,我有一些 hive 表,分区列 (dt) 是每个表包含的唯一列。

我在hive中执行下面的sql

SELECT * FROM (
SELECT row_number() over(ORDER BY T.dt) as row_num,T.* FROM 
(select * from ods.test_table where dt='2021-09-06') as T) TT 
WHERE TT.row_num BETWEEN 1 AND 10

我每次都得到相同的结果。

但是我在Presto中执行sql,结果不一样。我认为根本原因是我的表缺少唯一键。

是否可以在 Presto 中进行没有唯一键的全局查询?

【问题讨论】:

    标签: sql-order-by presto row-number deterministic non-deterministic


    【解决方案1】:

    您正在计算 row_number

    row_number() over(ORDER BY T.dt)
    

    并且 ORDER BY 列始终相同 dt='2021-09-06'。在这种情况下,row_number 具有不确定的行为,并且可以将相同的编号分配给不同的行。

    事实上,您在 Hive 中总是得到相同的结果是一个巧合,可能您总是使用完全相同数量的拆分运行,甚至在单个映射器上运行,该映射器运行单线程并产生看起来像确定性的结果。 Presto 可能具有不同的并行度,它会影响首先将哪些行传递给 row_number。

    您可以尝试更改拆分配置中的某些内容以强制使用更多映射器或增加数据大小,您将能够重现非确定性行为,许多在重负载集群上并行运行的映射器将以不同的速度和不同的行执行将传递给 row_number。

    要获得确定性结果,您可以将一些列添加到 ORDER BY 中,这将确定行的顺序。如果您没有此类列,则意味着您可以拥有任意数量的完全重复项。

    即使您没有唯一键,如果所有列都按顺序排列,row_number 也会产生确定性结果。

    考虑这个数据集:

    Col1 Col2 Col3
    1    1    2
    1    1    2
    1    1    3
    1    1    3
    

    row_number() over(ORDER BY col1) as rn 可以在每次运行时生成所有 4 行以不同的顺序排列(假设数据集非常大,并且有许多映射器同时运行,有些映射器可以更快地完成,有些可能会失败并重新启动)。当然,如果你有这么小的数据集,并且总是在单进程、单线程中处理它,结果会是一样的,但总的来说,数据库不是这样工作的。

    row_number() over(ORDER BY col1, col2)也一样

    但在row_number() over(ORDER BY col1, col2, col3) 的情况下 - 您将始终获得相同的数据集,保证。

    因此,解决方案是根据需要使用尽可能多的列顺序来确定行的顺序。在最坏的情况下,如果您有完全重复,则应将所有列添加到 ORDER BY,重复将一起排序,结果将是确定性的。

    【讨论】:

    • 按列添加顺序可以解决我的问题,但我认为它会影响性能
    • @YonghuiLu 是的。当然会影响,但是排序是 Hive 可以非常有效地做的事情,你不能白做。通常它应该是一些主键候选,考虑重新设计
    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 2020-01-25
    • 2022-12-31
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多