3.2 PromQL 与 SQL 方言对比


3.2 PromQL 与 SQL 方言对比

本节摘要:PromQL 是集合导向:一次选多条 series 再聚合;SQL 是表导向GROUP BY time_bucket。Influx Flux 管道过滤;QuestDB 标准 SQL + SAMPLE BY。本节用同一监控问题给出四家等价写法,并标注 Remote Write 后的查询归属。

本节导读

阅读完本节,你应当能够:

  1. 将 PromQL sum by 翻译为 Timescale SQL
  2. 说明 Prometheus 联邦与 SQL JOIN 维表的取舍
  3. 选择 QuestDB vs Timescale 做 ad-hoc 分析

一、问题与直觉

团队混用 Prometheus 采集 + Timescale 长期存 + Grafana 查询——面板报错常是语义没对齐:PromQL 的 ignoring/on 标签匹配,SQL 的 GROUP BY 列,Influx 的 _field 过滤,四套思维需一张对照表。2019 年后 SQL 复兴(Influx IOx、QuestDB、Timescale)让「会 SQL 就会时序」成为可能,但 PromQL 在监控模板库仍占主导。

二、核心原理

场景 A:按 service 求 5m QPS

引擎 写法
PromQL sum(rate(http_requests_total[5m])) by (service)
Timescale SELECT time_bucket('5m',time), service, sum(cnt)/300.0 FROM ... GROUP BY 1,2
Influx Flux |> aggregateWindow(every: 5m, fn: sum) |> derivative(...)
QuestDB SELECT ts, service, sum(requests)/300 FROM t SAMPLE BY 5m FILL(PREV)

场景 B:CPU 使用率 Top 5 host

引擎 写法
PromQL topk(5, avg by (host)(rate(cpu_seconds_total[5m])))
Timescale SELECT host, avg(cpu) ... GROUP BY host ORDER BY 2 DESC LIMIT 5
QuestDB 同上 SQL + LATEST ON ts PARTITION BY host
维度 PromQL SQL(Timescale/QuestDB)
数据模型 labels 集合 行 + 列
JOIN 维表 弱(需 export) 原生 JOIN
学习曲线 监控工程师熟悉 数据分析师熟悉
生态模板 kube-prometheus 丰富 需自建或转换

场景 C:P99 延迟(histogram)

histogram 在两边都能表达,但写法完全不同,这是迁移时最容易出错的地方:

# Prometheus:由桶计数近似分位数 histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
-- Timescale:用近似分位数聚合函数 SELECT time_bucket('5 min', time), approx_percentile(0.99, duration) FROM http_durations WHERE time > now() - interval '1 hour' GROUP BY 1;

注意两者语义差异:Prometheus 的 histogram_quantile 依赖客户端预分桶(_bucket 指标),Timescale 的 approx_percentile 直接对原始值做近似估计。同样的「P99」在两边的数值可能略有不同——迁移 dashboard 时不要期望逐点重合。

场景 D:同比对比

# Prometheus:同比(一周前同期),注意周对齐 sum(rate(http_requests_total[5m] offset 1w)) by (service)
-- Timescale:同一周期的绝对时间窗口 SELECT time_bucket('5 min', time), service, sum(cnt)/300.0 AS qps FROM http_requests WHERE time BETWEEN now() - interval '1 week' - interval '5 min' AND now() - interval '1 week' GROUP BY 1, 2;

PromQL 的 offset 1w 是「相对位移」,SQL 必须把位移换算成绝对时间范围;若目标周数据存在缺失 chunk,SQL 侧会产生空桶,而 PromQL 会把空桶隐式跳过——这就是「周对齐空桶导致假同比」的根源。

时间对齐规则对照

跨引擎查询对不上的另一个高频来源是窗口对齐规则不同:

引擎 默认对齐 空桶处理 备注
PromQL 查询步长(Grafana step) 无样本不返回 滑动窗口重叠
time_bucket UTC 整点 无行即缺 可传 offset
QuestDB SAMPLE BY 时间戳起算 需 FILL 显式指定 ALIGN TO CALENDAR
Flux aggregateWindow 开始时间起算 createEmpty 可配 固定桶

Remote Write 路径

Prometheus → VictoriaMetrics/Influx/Timescale 后,查询可在后端用 SQL 或 PromQL API(VM 兼容 PromQL)。OpenTelemetry collector 则可一次 export 多后端,避免双写逻辑分叉。

03-03-fig01-3

03-03-fig01-3

03-03-fig01-3

三、工程实践要点

需求 建议
K8s 默认 dashboard 保持 PromQL
与 ERP 维表 JOIN Timescale/QuestDB SQL
跨集群联邦 Prometheus federation 或 VM 单点查询
多租户隔离 label/tenant_id + RLS(Timescale)

Migrating 查询:Grafana 同一 panel 可切 datasource——迁移期双写双查,对比 rate 曲线是否重合(注意 step 与 alignment)。

双语迁移的推荐顺序

如果你要从「PromQL 为主」迁移到「SQL 为主」,建议按三个台阶走:第一步,保留 Prometheus 采集不动,把长期存储切到 SQL 引擎(Timescale/QuestDB),Grafana 面板逐步切 datasource;第二步,对高频面板做「PromQL vs SQL」双查询对比,确认语义一致后再下线 PromQL 版;第三步,把 recording rule 平移成 continuous aggregate 或物化视图。整个迁移期以「双写双查」为底线,避免一次性切换造成的监控空洞。

⚠️ 常见坑:把 PromQL offset 1w 同比直接写成 SQL 而不处理缺失 chunk——周对齐空桶导致假同比。

💡 关键直觉:PromQL 擅长「many series → one graph」;SQL 擅长「one table → join & window」——混合架构很常见,不是二选一。

自测题

  1. sum(rate(http_requests_total[5m])) by (service) 翻译成 Timescale SQL,注意单位换算。
  2. PromQL 的 offset 1w 同比为什么不能原样搬进 SQL?
  3. histogram 的 P99 在 Prometheus 与 Timescale 里有什么语义差异?

一节小结

  • PromQL:集合 + rate + by 标签
  • SQL:time_bucket / SAMPLE BY + GROUP BY
  • Remote Write:Prometheus 采集,SQL 库分析
  • QuestDB/Timescale:ad-hoc SQL 友好
  • OTel:统一摄取,多后端 export

后续章节将讨论写入路径性能与四大产品选型决策表(第4–6章,待续)。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U