Telemetry 的 DataFusion SQL 参考
Telemetry 使用 Apache DataFusion SQL 查询结构化事件表。 Telemetry 的公共配方目前在发布前使用 Apache DataFusion 45.2.0 进行规划和执行。此参考描述了该固定测试套件所执行的模式。
字段名称和类型仍然来自您的事件合同。使每个示例适应应用程序实际使用的表、单位、状态、标识规则和时间语义。
从有界读取开始
操作查询通常应以 UTC 时间过滤器开始,并仅返回问题所需的字段:
SELECT
route_template,
status_code,
latency_ms,
timestamp_utc
FROM api_requests
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
ORDER BY timestamp_utc DESC
LIMIT 100;
timestamp_utc 是服务器管理的查询时间戳。源提供的 timestamp 字段在摄取过程中进行标准化,不应替换配方中生成的查询列。
检查原始行时使用 LIMIT。对于完整导出,请使用 异步查询API,而不是从交互式查询中删除所有防护措施。
创建完整的时间段
date_trunc 为趋势创造了稳定的颗粒:
SELECT
date_trunc('hour', timestamp_utc) AS hour,
COUNT(*) AS requests
FROM api_requests
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY date_trunc('hour', timestamp_utc)
ORDER BY hour;
最新的一小时或一天可能仍然很满。当部分容量会使结果产生误导时,从告警中排除该存储桶。在每次比较中使用相同的时区、存储桶大小和完整性规则。
条件计数和安全率
条件 CASE 表达式计算同一分组行的多个结果:
SELECT
route_template,
COUNT(*) AS requests,
SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END) AS errors,
100.0 * SUM(CASE WHEN status_code >= 500 THEN 1 ELSE 0 END)
/ NULLIF(COUNT(*), 0) AS error_rate_pct
FROM api_requests
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route_template
HAVING COUNT(*) >= 20
ORDER BY error_rate_pct DESC;
NULLIF 保护分母为零的除法。乘以 100.0 可防止百分比算术变成整数除法。 HAVING 最小值可防止安静组中的一个故障的排名超过繁忙路由并产生有意义的影响。
百分位数和分布
使用 approx_percentile_cont(latency_ms, 0.95) 进行有效的 p95 估计:
SELECT
route_template,
approx_percentile_cont(latency_ms, 0.50) AS p50_ms,
approx_percentile_cont(latency_ms, 0.95) AS p95_ms,
approx_percentile_cont(latency_ms, 0.99) AS p99_ms
FROM api_requests
WHERE timestamp_utc >= now() - INTERVAL '24 hours'
GROUP BY route_template;
将 p50 与 p95 或 p99 进行比较。整个发行版的类似增长表明工作流程普遍较慢;较大的尾部变化表明存在异常缓慢的操作的子集。百分位数是估计值,因此请避免呈现微不足道的小数精度。
对于类似直方图的结果,请使用 CASE 将数值分配给显式存储桶。将存储桶标签和排序列分开,以便 "1000+" 不会在 "250–499" 之前排序。
CTE 使定义变得可审查
公共表表达式将业务定义与最终聚合分开:
WITH account_activity AS (
SELECT
account_id,
MIN(CASE WHEN event_name = 'signup_completed' THEN timestamp_utc END)
AS signed_up_at,
MIN(CASE WHEN event_name = 'activation_completed' THEN timestamp_utc END)
AS activated_at
FROM product_events
WHERE timestamp_utc >= now() - INTERVAL '30 days'
GROUP BY account_id
)
SELECT
COUNT(*) AS signed_up_accounts,
SUM(CASE WHEN activated_at IS NOT NULL THEN 1 ELSE 0 END)
AS activated_accounts
FROM account_activity
WHERE signed_up_at IS NOT NULL;
通过临时从中选择来检查中间 CTE。这通常是捕获重复标识、意外空值或包含错误行的里程碑定义的最快方法。
连接需要明确的粒度
在连接事件表之前,请说明每一行代表什么。多对多联接可以增加计数,同时仍返回有效的 SQL。
当作为分析单位时,在加入之前将每个帐户、请求、作业、Webhook 交付或计费周期预先聚合到一行。使用为关联而创建的稳定标识符,切勿仅仅因为显示标签看起来唯一而加入它。
连接后,比较:
- 之前和之后的行数
- 之前和之后的不同标识符计数
- 两侧不匹配的行
- 与已知结果的赛程的总计
窗口函数
窗口函数在比较相邻值时保留行或存储桶的详细信息:
WITH daily AS (
SELECT
date_trunc('day', timestamp_utc) AS day,
COUNT(*) AS completed_jobs
FROM job_events
WHERE status = 'completed'
AND timestamp_utc >= now() - INTERVAL '30 days'
GROUP BY date_trunc('day', timestamp_utc)
)
SELECT
day,
completed_jobs,
LAG(completed_jobs) OVER (ORDER BY day) AS previous_day_jobs,
AVG(completed_jobs) OVER (
ORDER BY day
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS rolling_7_bucket_average
FROM daily
ORDER BY day;
LAG 公开以前的值。带框架的 AVG 创建滚动基线。前面几排的窗户不完整;在创建告警之前决定是显示它们、抑制它们还是标记它们。
嵌套字段和标识符
Telemetry 通过点状字段路径公开嵌套的 JSON。如果在当前表模式中需要引用点路径,请使用双引号标识符,例如 "data.tool.name"。在复制嵌套字段查询之前,请阅读 查询嵌套JSON 并检查表架构。
设计新事件时,使用 Snake_case 字段名称并避免保留或不明确的单词。如果现有字段需要引用,请一致地引用它,而不是创建同一概念的两种拼写。
支持的模式和固定限制
测试的配方套件练习 SELECT、CTE、连接、CASE、常见聚合、date_trunc、间隔、近似百分位数、LAG、框架窗口、NULLIF、COALESCE、排序、分组和限制。
DataFusion 不是 PostgreSQL、MySQL、BigQuery 或 Snowflake。外观相似的函数可以有不同的名称或签名。 Telemetry 的配方审核使用的固定计划程序不接受这些系统中找到的每个聚合修改器或日期帮助程序。首选本参考文献和经过测试的 SQL配方库 中演示的语法,然后在改编另一种方言的示例之前运行一个小型查询。
查询审核清单
在保存查询或在告警中使用它之前:
- 确认表、列、类型、单位和 UTC 时间范围。
- 定义参与者或工作流标识符并验证行粒度。
- 决定重试、重复、延迟事件、空值和不完整存储桶的行为方式。
- 通过分母检查和最小有意义的数量来保护比率。
- 检查中间 CTE 和连接行数。
- 测试综合成功、失败、重试、重复和边界情况。
- 在结果旁边记录定义、所有者、阈值和预期响应。
每个配方都包含模式、可复制的 SQL、确定性合成输出、可视化、解释注释、边缘案例、仪表板建议和告警指导。读取 SQL测试方法,然后从 API 可靠性、产品分析、数据质量 或 基础设施 开始。