您可以在其他连续聚合之上创建连续聚合。这允许您在不同的粒度级别汇总数据。例如,您可能有一个按小时的连续聚合,用于汇总每分钟的数据。要获得每日摘要,您可以在按小时的聚合之上创建一个新的连续聚合。这比在原始超表之上创建每日聚合更有效,因为您可以重用来自按小时聚合的计算结果。

此功能在 Timescale 2.9 及更高版本中可用。

在另一个连续聚合之上创建连续聚合的工作方式与在超表之上创建连续聚合的方式相同。在您的查询中,从连续聚合而不是从超表中选择,并使用现有连续聚合中的时间分桶列作为您的时间列。

有关更多信息,请参阅创建连续聚合的说明。

默认情况下,所有连续聚合都使用实时聚合。这意味着它们始终返回最新的数据以响应查询。它们通过将连续聚合中的物化数据与来自源表或视图的未物化原始数据连接来实现此目的。

当连续聚合堆叠时,每个连续聚合仅知道紧邻其下方的层。未物化数据的连接递归发生,直到到达底层,使您可以访问到该层级的最新数据。

如果您将堆栈中的所有连续聚合都保留为实时聚合,则底层是源超表。这意味着堆栈中的每个连续聚合都可以访问所有最新数据。

如果堆栈中的某个位置存在非实时连续聚合,则递归连接会在该非实时连续聚合处停止。更高级别的连续聚合不会从较低级别接收任何未物化数据。

例如,假设您有以下连续聚合

  • 源超表上的实时按小时连续聚合
  • 按小时连续聚合上的实时按日连续聚合
  • 按日连续聚合上的非实时或仅物化按月连续聚合
  • 按月连续聚合上的实时按年连续聚合

对按小时和按日连续聚合的查询包括来自源超表的实时、非物化数据。对按月连续聚合的查询仅返回已物化的数据。对按年连续聚合的查询返回来自按年连续聚合本身的物化数据,以及来自按月连续聚合的更新数据。但是,数据仅限于按月连续聚合中已物化的内容,并且不会从源超表获取更近期的更新数据。发生这种情况是因为仅物化的连续聚合提供了一个停止点,并且按年连续聚合不知道超出该停止点的任何层。这类似于PostgreSQL 中堆叠视图的工作方式

要使对按年连续聚合的查询访问所有最新数据,您可以

  • 使按月连续聚合成为实时的,或者
  • 在按日连续聚合之上重新定义按年连续聚合。
Example of hierarchical continuous aggregates in a finance application

在汇总已汇总的数据时,请注意堆叠计算的工作方式。并非所有计算在堆叠时都会返回正确的结果。

例如,如果您取几个子集的最大值,然后取这些最大值的最大值,您将得到整个集合的最大值。但是,如果您取几个子集的平均值,然后取这些平均值的平均值,则结果可能与所有数据的平均值不同。

为了在使用连续聚合在连续聚合之上时简化此类计算,您可以使用 TimescaleDB Toolkit 中的超函数,例如统计聚合。这些超函数采用两步聚合模式设计,允许您将它们汇总到更大的桶中。第一步创建一个可以汇总的摘要聚合,就像最大值可以汇总一样。您可以将此聚合存储在您的连续聚合中。然后,当您从连续聚合查询时,您可以调用访问器函数作为第二步。此访问器从摘要聚合中获取存储的数据并返回最终结果。

例如,您可以使用超表上的 percentile_agg 创建一个按小时的连续聚合,如下所示

CREATE MATERIALIZED VIEW response_times_hourly
WITH (timescaledb.continuous)
AS SELECT
time_bucket('1 h'::interval, ts) as bucket,
api_id,
avg(response_time_ms),
percentile_agg(response_time_ms) as percentile_hourly
FROM response_times
GROUP BY 1, 2;

然后,要在其上堆叠另一个按日连续聚合,您可以使用 rollup 函数,如下所示

CREATE MATERIALIZED VIEW response_times_daily
WITH (timescaledb.continuous)
AS SELECT
time_bucket('1 d'::interval, bucket) as bucket_daily,
api_id,
mean(rollup(percentile_hourly)) as mean,
rollup(percentile_hourly) as percentile_daily
FROM response_times_hourly
GROUP BY 1, 2;

TimescaleDB Toolkit 的 mean 函数用于计算汇总值的具体平均值。附加的 percentile_daily 属性包含原始汇总值,这些值可以用于此连续聚合之上的附加连续聚合(例如,每日值的连续聚合)。

有关使用 rollup 函数堆叠计算的更多信息和示例,请参阅百分位数近似 API 文档

在另一个连续聚合之上创建连续聚合时,存在一些限制。在大多数情况下,这些限制是为了确保有效的时间分桶

  • 您只能在已完成的连续聚合之上创建连续聚合。这种新的完成格式是自 Timescale 2.7 以来创建的所有连续聚合的默认格式。如果您需要在旧格式的连续聚合之上创建连续聚合,您需要先迁移您的连续聚合到新格式。

  • 连续聚合的时间桶应大于或等于底层连续聚合的时间桶。它还需要是底层时间桶的倍数。例如,您可以将按小时的连续聚合重新分桶为新的连续聚合,时间桶为 6 小时。您不能将按小时的连续聚合重新分桶为新的连续聚合,时间桶为 90 分钟,因为 90 分钟不是 1 小时的倍数。

  • 具有固定宽度时间桶的连续聚合不能在具有可变宽度时间桶的连续聚合之上创建。固定宽度时间桶是在秒、分钟、小时和天中定义的时间桶,因为这些时间间隔始终长度相同。可变宽度时间桶是在月或年中定义的时间桶,因为这些时间间隔因月份或闰年而异。此限制是为了防止出现例如尝试将每月桶重新分桶为 61 天桶的情况,其中月份组合(如七月/八月(62 天))的时间桶之间没有良好的映射。

    请注意,即使周是固定宽度间隔,您也不能在每周时间桶之上使用每月或每年时间桶,原因相同。一个月或一年中的周数通常不是整数。

    但是,您可以在固定宽度时间桶之上堆叠可变宽度时间桶。例如,在按日连续聚合之上创建按月连续聚合是可行的,并且是此功能的主要用例之一。

关键词

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