HyperLogLog 函数

Presto 使用 HyperLogLog 数据结构实现 approx_distinct() 函数。

数据结构

Presto 将 HyperLogLog 数据草图实现为一组 32 位桶,这些桶存储 *最大哈希*。它们可以稀疏地存储(作为从桶 ID 到桶的映射),也可以密集地存储(作为连续内存块)。HyperLogLog 数据结构从稀疏表示开始,在效率更高时切换到密集表示。P4HyperLogLog 结构密集初始化,并在其整个生命周期内保持密集。

HyperLogLog 隐式转换为 P4HyperLogLog,而可以使用显式转换将 HyperLogLog 转换为 P4HyperLogLog

cast(hll AS P4HyperLogLog)

序列化

数据草图可以序列化到 varbinary 并从 varbinary 反序列化。这使它们可以存储以供将来使用。结合合并多个草图的能力,这使得能够以极低的成本计算 :func:!approx_distinct` 查询中元素的分区,然后计算整个查询的元素。

例如,计算每日唯一用户的 HyperLogLog 将允许通过合并每日数据来增量计算每周或每月唯一用户。这类似于通过对每日收入求和来计算每周收入。使用 approx_distinct()GROUPING SETS 可以转换为使用 HyperLogLog。示例

CREATE TABLE visit_summaries (
  visit_date date,
  hll varbinary
);

INSERT INTO visit_summaries
SELECT visit_date, cast(approx_set(user_id) AS varbinary)
FROM user_visits
GROUP BY visit_date;

SELECT cardinality(merge(cast(hll AS HyperLogLog))) AS weekly_unique_users
FROM visit_summaries
WHERE visit_date >= current_date - interval '7' day;

函数

approx_set(x) -> HyperLogLog()

返回输入数据集 xHyperLogLog 草图。最大标准误差的值默认为 0.01625。此数据草图是 approx_distinct() 的基础,可以通过调用 cardinality() 来存储和稍后使用。

approx_set(x, e) -> HyperLogLog()

返回输入数据集 xHyperLogLog 草图,最大标准误差为 e。此函数的当前实现要求 e 处于范围 [0.0040625, 0.26000] 内。此数据草图是 approx_distinct() 的基础,可以通过调用 cardinality() 来存储和稍后使用。

cardinality(hll) -> bigint()

这将对由 hll HyperLogLog 数据草图汇总的数据执行 approx_distinct()

empty_approx_set() -> HyperLogLog()

返回一个空的 HyperLogLog。最大标准误差的值默认为 0.01625

empty_approx_set(e) -> HyperLogLog()

返回一个空的 HyperLogLog,最大标准误差为 e。此函数的当前实现要求 e 处于范围 [0.0040625, 0.26000] 内。

merge(HyperLogLog) -> HyperLogLog()

返回各个 hll HyperLogLog 结构的聚合并集的 HyperLogLog

merge_hll(array(HyperLogLog)) -> HyperLogLog()

返回数组 hll HyperLogLog 结构的并集的 HyperLogLog