简介

使用 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 上编辑此页面