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

如何在PostgreSQL中实现轮询(Round-robin)查询?

我来帮你搞定PostgreSQL里的轮询(Round-robin)查询需求,结合你给出的表结构,咱们分场景来实现:

首先先明确核心逻辑:轮询的本质是每次选择上次执行时间最早的检查组合(站点+地域),如果是首次执行则按固定顺序依次触发。我假设你的checks_requests表包含check_id、location_id和request_time(记录每次检查的时间)字段,如果结构略有不同,你可以微调字段名即可。


场景1:全局轮询所有检查组合

这个场景下,所有需要执行的(check_id, location_id)组合统一排序,每次选最久没执行的那个,适合所有检查任务优先级相同的情况。

实现SQL

-- 查询下一个要执行的轮询任务
SELECT 
    cl.check_id, 
    cl.location_id, 
    c.site, 
    l.location,
    COALESCE(MAX(cr.request_time), '1970-01-01'::TIMESTAMP) AS last_request_time
FROM checks_locations cl
JOIN checks c ON cl.check_id = c.id
JOIN locations l ON cl.location_id = l.id
LEFT JOIN checks_requests cr 
    ON cl.check_id = cr.check_id 
    AND cl.location_id = cr.location_id
GROUP BY cl.check_id, cl.location_id, c.site, l.location
-- 优先按上次执行时间升序,时间相同则按ID保证稳定排序
ORDER BY last_request_time ASC, cl.check_id ASC, cl.location_id ASC
LIMIT 1;

关键说明

  • 用LEFT JOIN关联请求记录表,确保从未执行过的检查组合也能被选中
  • COALESCE把空的执行时间替换成极早的时间(1970年),让未执行的任务排在最前面
  • 每次执行完任务后,记得往checks_requests插入一条记录,更新执行时间:
    INSERT INTO checks_requests (check_id, location_id) VALUES (选中的check_id, 选中的location_id);
    

场景2:按站点独立轮询地域

如果希望每个站点的地域先内部轮流,再在各站点的候选任务中选择(避免某个高频站点抢占所有资源),可以用窗口函数实现:

实现SQL

WITH check_location_rank AS (
    SELECT 
        cl.check_id, 
        cl.location_id, 
        c.site, 
        l.location,
        cr.request_time,
        -- 按站点分组,给每个站点下的地域按执行时间排序
        ROW_NUMBER() OVER (
            PARTITION BY cl.check_id 
            ORDER BY COALESCE(cr.request_time, '1970-01-01') ASC
        ) AS rank_in_check
    FROM checks_locations cl
    JOIN checks c ON cl.check_id = c.id
    JOIN locations l ON cl.location_id = l.id
    LEFT JOIN checks_requests cr 
        ON cl.check_id = cr.check_id 
        AND cl.location_id = cr.location_id
),
per_check_next_task AS (
    -- 每个站点选最早需要执行的地域
    SELECT * FROM check_location_rank WHERE rank_in_check = 1
)
-- 从各站点的候选任务中,选全局最久未执行的那个
SELECT * FROM per_check_next_task
ORDER BY COALESCE(request_time, '1970-01-01') ASC, check_id ASC
LIMIT 1;

关键说明

  • 先用窗口函数ROW_NUMBER()给每个站点下的地域排序,选出每个站点的下一个候选任务
  • 再从所有站点的候选中选全局优先级最高的,保证每个站点的地域都能轮流被执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:42:10