简介

使用 t-digest 算法估计给定百分位数的值或给定值的百分位数排名。这种估计比使用 PostgreSQL 的 percentile_contpercentile_disc 函数进行精确计算更节省内存和 CPU 资源。

tdigest 是 TimescaleDB 工具包提供的两种高级百分位数近似聚合之一。它是一种空间效率高的聚合,并且与传统方法相比,它在极端分位数中提供了更准确的估计。

tdigest 在一定程度上依赖于输入顺序。如果 tdigest 在以不同顺序排列的相同数据上运行,结果应该几乎相等,但不太可能完全相同。

另一个高级百分位数近似聚合是 uddsketch,它在保证的相对误差内产生稳定估计。如果您不确定使用哪个,请尝试默认百分位数估计方法,percentile_agg。它使用 uddsketch 算法以及一些合理的默认值。

有关百分位数近似算法的更多信息,请参阅 算法概述

相关超函数组

聚合

tdigest
tdigest 中聚合数据以进一步计算百分位数估计

访问器

approx_percentile
tdigest 中估计给定百分位数的值
approx_percentile_rank
tdigest 中估计给定值的百分位数
mean
tdigest 中的值计算精确的平均值
num_vals
获取 tdigest 中包含的值数量

汇总

rollup
汇总多个 tdigest
tdigest(
buckets INTEGER,
value DOUBLE PRECISION
) RETURNS TDigest

这是使用 tdigest 算法计算近似百分位数的第一步。使用 tdigest 从原始数据创建中间聚合。然后,可以使用此组中的一个或多个访问器来计算最终结果。

或者,可以在应用访问器之前使用 rollup() 将多个这样的中间聚合对象组合起来。

必需参数
名称类型描述
bucketsINTEGER摘要中的桶数。增加此值可以提供更准确的分位数估计,但需要更多内存。
valueDOUBLE PRECISION要为 tdigest 对象聚合的值的列。
返回值
类型描述
tdigestTDigest创建的百分位数估计器对象,用于使用 tdigest 算法计算百分位数
示例

假设有一个名为 samples 的表,其中包含名为 data 的列,使用 data 列构建 tdigest。为近似值使用 100 个桶

SELECT tdigest(100, data) FROM samples;
approx_percentile(
percentile DOUBLE PRECISION,
tdigest TDigest
) RETURNS DOUBLE PRECISION

tdigest 聚合中估计近似百分位数的值。

必需参数
名称类型描述
percentileDOUBLE PRECISION要计算的百分位数。必须在范围 [0.0, 1.0] 内。
tdigestTDigesttdigest 聚合。
返回值
类型描述
approx_percentileDOUBLE PRECISION请求百分位数处的估计值。
示例

估计第一个百分位数的值,假设样本包含从 0 到 100 的数字

SELECT
approx_percentile(0.01, tdigest(data))
FROM generate_series(0, 100) data;
approx_percentile
-------------------
0.999
approx_percentile_rank(
value DOUBLE PRECISION,
digest TDigest
) RETURNS DOUBLE PRECISION

估计给定值将位于哪个百分位数。

必需参数
名称类型描述
valueDOUBLE PRECISION要估计百分位数的值。
digestTDigesttdigest 聚合。
返回值
类型描述
approx_percentile_rankDOUBLE PRECISION与提供的值相关的估计百分位数。
示例

估计值 99 的百分位数排名,假设样本包含从 0 到 100 的数字

SELECT
approx_percentile_rank(99, tdigest(data))
FROM generate_series(0, 100) data;
approx_percentile_rank
----------------------------
0.9851485148514851
mean(
digest TDigest
) RETURNS DOUBLE PRECISION

计算 tdigest 聚合中值的精确平均值。与百分位数计算不同,平均值计算是精确的。此访问器允许您在不需要从相同原始数据创建两个独立的聚合的情况下,计算平均值和百分位数。

必需参数
名称类型描述
digestTDigest要从中提取平均值的 tdigest 聚合。
返回值
类型描述
meanDOUBLE PRECISIONtdigest 聚合中值的平均值。
示例

计算从 0 到 100 的整数的平均值

SELECT mean(tdigest(data))
FROM generate_series(0, 100) data;
mean
------
50
num_vals(
digest TDigest
) RETURNS DOUBLE PRECISION

获取 tdigest 聚合中包含的值数量。此访问器允许您在不需要从相同原始数据创建两个独立的聚合的情况下,计算计数和百分位数。

必需参数
名称类型描述
digestTDigest要从中提取值数量的 tdigest 聚合。
返回值
类型描述
num_valsDOUBLE PRECISIONtdigest 聚合中的值数量。
示例

计算从 0 到 100 的整数的数量

SELECT num_vals(tdigest(data))
FROM generate_series(0, 100) data;
num_vals
-----------
101
rollup(
digest TDigest
) RETURNS TDigest

tdigest 生成的多个中间 tdigest 聚合组合到单个中间 tdigest 聚合中。例如,您可以使用 rollup 将 15 分钟桶的 tdigest 组合成每日桶。

必需参数
名称类型描述
digestTDigest要汇总的 tdigest
返回值
类型描述
rollupTDigest通过组合输入 tdigest 创建的新的 tdigest

创建一个包含百分位数聚合的小时连续聚合

CREATE MATERIALIZED VIEW foo_hourly
WITH (timescaledb.continuous)
AS SELECT
time_bucket('1 h'::interval, ts) as bucket,
tdigest(value) as tdigest
FROM foo
GROUP BY 1;

您可以使用访问器直接从连续聚合查询小时数据。您还可以将小时数据汇总到每日桶中,然后计算近似百分位数

SELECT
time_bucket('1 day'::interval, bucket) as bucket,
approx_percentile(0.95, rollup(tdigest)) as p95,
approx_percentile(0.99, rollup(tdigest)) as p99
FROM foo_hourly
GROUP BY 1;

关键词

发现此页面上的问题?报告问题 或 在 GitHub 上编辑此页面