Timescale 使用近似算法来计算百分位数,而无需所有数据。 这也使它们更兼容连续聚合。 默认情况下,Timescale 使用 uddsketch,但您也可以选择使用 tdigest。 本节介绍不同的方法,并帮助您决定应该使用哪一种。

uddsketch 是默认算法。 它使用指数大小的桶来保证近似值落在相对于真实离散百分位数的已知误差范围内。 此算法允许调整草图的大小和最大误差目标。

tdigest 将数据更积极地分桶到分位数范围的中心,使其在范围的尾部(大约 0.001 或 0.995 附近)具有更高的精度。

每种算法都有不同的特性,这可能使一种算法比另一种更好,具体取决于您的用例。 以下是选择算法时要考虑的一些差异

在开始之前,重要的是要了解百分位数的正式定义是不精确的,并且有不同的方法来确定真实的百分位数实际上是什么。 在 PostgreSQL 中,给定目标百分位数 ppercentile_disc 返回集合的最小元素,以便集合的 p 百分比小于该元素。 但是,percentile_cont 返回 p 的两个最近匹配项之间的插值。 在实践中,这些方法之间的差异非常小,但是,如果这对您的用例很重要,请记住 tdigest 近似于连续百分位数,而 uddsketch 提供离散值的估计值。

考虑一下您最感兴趣的百分位数类型。 tdigest 针对极端情况下更准确的估计进行了优化,而对中位数附近的估计则不太准确。 如果您的工作流程涉及估计第 99 个百分位数,请选择 tdigest。 如果您更关心获得高度准确的中位数估计,请选择 uddsketch

这些算法在估计数据的方式上有所不同。 uddsketch 具有稳定的分桶函数,因此对于相同的底层数据,无论其排序或重新聚合方式如何,它始终返回相同的百分位数估计值。 另一方面,tdigest 基于附近点的平均值构建增量桶,除非严格控制聚合的顺序和批处理(这在 PostgreSQL 中有时很难做到),否则可能会导致基于相同数据的估计值存在一些细微差异。 如果稳定的估计对您很重要,请选择 uddsketch

tdigest 计算精确的误差条可能很困难,尤其是在将多个子摘要合并为一个更大的摘要时。 这可能通过摘要聚合或正常点聚合的并行化发生。 如果您需要严格描述您的误差,请选择 uddsketch。 但是,由于 uddsketch 使用指数分桶来提供有保证的相对误差,如果数据集覆盖很大的范围,则可能会导致一些非常大的绝对误差。 例如,如果数据均匀分布在范围 [1,100] 上,则百分位数范围高端的估计值的绝对误差大约是低端的 100 倍。 如果数据范围是 [0,100],则这种情况会变得更加极端。 如果稳定的绝对误差对您的用例很重要,请选择 tdigest

虽然两种算法都可能随着未来的优化而变得更小更快,但 uddsketch 通常比 tdigest 需要更小的内存占用,并且对于任何连续聚合,磁盘占用也相应更小。 无论您选择哪种算法,提高百分位数估计准确性的最佳方法是增加桶的数量,这使用 uddsketch 更简单。 如果您的用例没有从使用 tdigest 中获得明显的优势,则默认的 uddsketch 是您的最佳选择。

有关不同算法的更多技术细节和使用示例,请参阅 uddsketchtdigest 的开发者文档。

关键词

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