了解持续查询中的窗口聚合
BigQuery 持续查询支持将聚合和开窗作为有状态操作,以便您分析多行或多个时间间隔内的流式数据。借助此功能,您可以在持续查询运行期间将必要的状态存储在内存中,从而计算一段时间内的指标(例如 30 分钟平均值)。
关于窗口函数
窗口函数根据系统时间将数据分配到逻辑组件或窗口,系统时间表示进行更改的事务的提交时间。在 BigQuery 中,这些函数是表值函数 (TVF),可返回一个包含所有原始列和两个附加列(window_start 和 window_end)的表。这些列用于标识每个窗口的时间间隔。如需详细了解有状态操作,请参阅支持的有状态操作。
只有 BigQuery 持续查询支持开窗 TVF。
窗口化 TVF 与窗口函数调用不同。
支持的聚合函数
支持以下聚合函数:
ANY_VALUEAPPROX_COUNT_DISTINCTAPPROX_QUANTILESAPPROX_TOP_COUNTAPPROX_TOP_SUMARRAY_AGG,具有以下要求:LIMIT子句是必需的,最大值为 10,000。ORDER BY子句是可选的。
ARRAY_CONCAT_AGGAVGBIT_ANDBIT_ORBIT_XORCORRCOUNTCOUNTIFCOVAR_POPCOVAR_SAMPLOGICAL_ANDLOGICAL_ORMAXMAX_BYMINMIN_BYSTDDEVSTDDEV_POPSTDDEV_SAMPSTRING_AGG,具有以下要求:LIMIT子句是必需的,最大值为 100。ORDER BY子句是可选的。
SUMVAR_POPVAR_SAMPVARIANCE
不受支持的聚合函数
不支持以下聚合函数:
AVG(差分隐私)COUNT(差分隐私)- 包含
DISTINCT表达式的函数。 GROUPINGPERCENTILE_CONT(差分隐私)ST_CENTROID_AGGST_EXTENTST_UNION_AGGSUM(差分隐私)
TUMBLE 函数
TUMBLE 函数会将数据分配到指定大小的非重叠时间间隔(翻滚窗口)中。例如,5 分钟的窗口会将事件分组到离散的时间间隔内,例如 [2026-01-01 12:00:00, 2026-01-01 12:05:00) 和 [2026-01-01 12:05:00, 2026-01-01 12:10:00)。时间戳值为 2026-01-01 12:03:18 的行会分配给第一个窗口。由于这些窗口不相交且不重叠,因此每个带有时间戳的元素都恰好分配给一个窗口。
下图展示了 TUMBLE 函数如何将事件分配到不重叠的时间间隔:
您可以在实时事件处理中使用此函数,在执行任何聚合之前按时间范围对事件进行分组。
语法
TUMBLE(TABLE table, "timestamp_column", window_size)
定义
table:BigQuery 表名称。这必须是封装在APPENDS函数中的标准 BigQuery 表。此参数必须以TABLE一词开头。timestamp_column:STRING字面量,用于指定输入表中包含事件时间的列的名称。此列中的值会将每一行分配给一个窗口。_CHANGE_TIMESTAMP列用于定义 BigQuery 系统时间,是唯一受支持的timestamp_column。不支持用户定义的列。window_size:用于定义每个翻滚窗口时长的INTERVAL值。时间范围最长可达 24 小时。例如:INTERVAL 30 SECOND。
输出
TUMBLE 函数会返回包含以下列的输出:
运行查询时输入表的所有列。
window_start:一个TIMESTAMP值,表示记录所属窗口的开始时间(包含)。window_end:一个TIMESTAMP值,表示记录所属窗口的结束时间(不含边界值)。
输出具体化
在 BigQuery 持续查询中,窗口化聚合不会为特定时间间隔生成输出,直到 BigQuery 完成或关闭该窗口。此行为可确保 BigQuery 仅在处理该窗口的所有相关数据后才发出汇总结果。
例如,如果您对 user_clickstream 表执行 5 分钟的 TUMBLE 窗口聚合,则只有在查询处理 _CHANGE_TIMESTAMP 为 10:20 或更晚时间的记录后,系统才会发出时间间隔 [10:15; 10:20) 的结果。此时,BigQuery 会认为窗口已关闭。
此外,当属于该特定时间范围的第一条记录出现时,窗口会打开并开始累积数据。
当窗口保持打开状态时,BigQuery 必须保留中间聚合结果。这需要存储状态,这意味着 BigQuery 必须保留中间聚合结果。由于此状态必须保留在活跃内存中,直到窗口关闭,因此使用较长的窗口时长或处理大量数据流会导致槽利用率提高,以便管理增加的存储上下文量。如需了解详情,请参阅价格注意事项。
限制
- 只有 BigQuery 持续查询支持
TUMBLE函数。 - 使用
TUMBLE函数启动持续查询时,您只能使用APPENDS函数。不支持CHANGES函数。 - 由
_CHANGE_TIMESTAMP定义的 BigQuery 系统时间列是唯一受支持的timestamp_column。不支持用户定义的列。 - 时间范围最长可达 24 小时。
TUMBLE窗口函数运行时,会生成两个额外的输出列:window_start和window_end。您必须在执行窗口聚合的SELECT语句中的GROUP BY语句中包含其中至少一个列。- 将
TUMBLE函数与持续查询联接结合使用时,您必须遵循所有持续查询联接限制。
价格注意事项
BigQuery 持续查询会根据作业运行期间消耗的计算容量(槽)向您收费。这种基于计算的模型也适用于有状态操作,例如窗口化。由于开窗要求 BigQuery 在查询处于活跃状态时存储“状态”,因此会消耗额外的槽资源。一般来说,窗口中存储的上下文或数据越多(例如使用较长的窗口时长时),BigQuery 必须保留的状态就越多。这会导致槽利用率提高。
示例
以下查询展示了如何查询出租车行程表,以获取每 30 分钟的流式平均行程数、乘客数和每辆出租车的平均车费,并将这些数据导出到 BigQuery 中的表中:
INSERT INTO
`real_time_taxi_streaming.driver_stats`
WITH ride_completions AS (
SELECT
_CHANGE_TIMESTAMP as bq_changed_ts,
CAST(timestamp AS DATE) AS ride_date,
taxi_id,
meter_reading,
passenger_count
FROM
APPENDS(TABLE `real_time_taxi_streaming.taxirides`,
CURRENT_TIMESTAMP() - INTERVAL 10 MINUTE)
WHERE
ride_status = 'dropoff')
SELECT
ride_date,
window_end,
taxi_id,
COUNT(taxi_id) AS total_rides_per_half_hour,
ROUND(AVG(meter_reading),2) AS avg_fare_per_half_hour,
SUM(passenger_count) AS total_passengers_per_half_hour
FROM
tumble(TABLE ride_completions,"bq_changed_ts",INTERVAL 30 MINUTE)
GROUP BY
window_end,
ride_date,
taxi_id
后续步骤
- 了解如何执行 JOIN、聚合和窗口化操作。
- 详细了解 BigQuery 持续查询。
- 了解如何联接来自多个数据流的数据。