You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写PostgreSQL递归查询计算树状网络根请求平均延迟

树状请求根节点平均网络延迟计算方案

问题说明

要计算树状主机网络里所有根请求的平均网络延迟。每个根请求的延迟是它整个请求树里所有RequestSent/RequestReceived、ResponseSent/ResponseReceived事件对的时间差之和。比如测试数据里两个根请求延迟分别是284ms和15ms,平均就是149.5ms。

原查询问题解析

你写的非递归查询算出了负值,问题出在两点:

  • 关联逻辑搞反:t1.request_id = t2.parent_request_id这个关联把事件对的归属弄反了,导致有些发送时间比接收时间晚,算出来的时间差是负数。
  • 没处理树状层级:非递归只能关联直接的父子请求,没法遍历整个请求树,会漏掉深层子节点的事件对,延迟计算肯定不全。

递归查询解决办法

用PostgreSQL的递归CTE(WITH RECURSIVE)遍历整个请求树,把所有关联的事件对都收集到,再汇总根请求的总延迟,最后算平均值:

WITH RECURSIVE request_tree AS (
    -- 先抓所有根请求:parent_request_id为空的RequestReceived事件对应的request_id
    SELECT 
        r.request_id AS root_id,
        r.request_id AS current_id
    FROM requests r
    WHERE r.parent_request_id IS NULL 
      AND r.type = 'RequestReceived'
    
    UNION ALL
    
    -- 递归遍历所有子请求,把每个子请求绑定到对应的根请求
    SELECT 
        rt.root_id,
        r.request_id AS current_id
    FROM request_tree rt
    JOIN requests r ON rt.current_id = r.parent_request_id
),
-- 收集所有要计算的有效事件对
event_pairs AS (
    -- 父请求发RequestSent,子请求收RequestReceived的时间差
    SELECT
        rt.root_id,
        (r_received.datetime - r_sent.datetime) * 1000 AS latency
    FROM requests r_sent
    JOIN requests r_received 
        ON r_sent.request_id = r_received.parent_request_id
        AND r_sent.type = 'RequestSent'
        AND r_received.type = 'RequestReceived'
    JOIN request_tree rt ON r_sent.request_id = rt.current_id
    
    UNION ALL
    
    -- 子请求发ResponseSent,父请求收ResponseReceived的时间差
    SELECT
        rt.root_id,
        (r_received.datetime - r_sent.datetime) * 1000 AS latency
    FROM requests r_sent
    JOIN requests r_received 
        ON r_sent.parent_request_id = r_received.request_id
        AND r_sent.type = 'ResponseSent'
        AND r_received.type = 'ResponseReceived'
    JOIN request_tree rt ON r_sent.request_id = rt.current_id
),
-- 算出每个根请求的总延迟
root_latency AS (
    SELECT
        root_id,
        SUM(latency) AS total_latency
    FROM event_pairs
    GROUP BY root_id
)
-- 最后算所有根请求的平均延迟
SELECT AVG(total_latency) AS average_latency
FROM root_latency;

代码说明

  • request_tree递归CTE:从根请求开始,把所有子请求都关联到对应的根ID,确保整个请求树里的事件都能归到正确的根请求下。
  • event_pairsCTE:分两类收集事件对的时间差,所有事件对都通过request_tree绑定到根请求。
  • root_latencyCTE:按根ID汇总所有时间差,得到每个根请求的总延迟。
  • 最后一步计算所有根请求总延迟的平均值。

用测试数据跑的话,会正确算出ID0总延迟284ms、ID4总延迟15ms,平均149.5ms。

内容的提问来源于stack exchange,提问作者dodekaedr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 17:12:46