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

如何查询聊天室用户数量峰值时间段?MySQL/ClickHouse方案探讨

找出聊天室用户最多时段的高效查询方案

MySQL 实现方案

核心思路

通过拆分用户的进入/离开事件,计算每个时间点的累计在线人数,再定位在线人数峰值的连续时间段:

  1. 拆分所有时间节点:将enter_time标记为用户增加事件(+1),leave_time标记为用户减少事件(-1);
  2. 按时间排序,用窗口函数计算累计在线人数;
  3. 找出最大在线人数,合并连续的峰值时间段。

完整查询SQL

WITH event_points AS (
    -- 拆分用户进入事件
    SELECT enter_time AS event_time, 1 AS user_change FROM user_log
    UNION ALL
    -- 拆分用户离开事件
    SELECT leave_time AS event_time, -1 AS user_change FROM user_log
),
cumulative_users AS (
    -- 计算每个时间点的累计在线人数
    SELECT 
        event_time,
        SUM(user_change) OVER (ORDER BY event_time) AS online_users,
        -- 获取下一个时间点的在线人数
        LEAD(SUM(user_change) OVER (ORDER BY event_time)) OVER (ORDER BY event_time) AS next_online_users
    FROM event_points
    WHERE DATE(event_time) = '2022-09-10' -- 指定查询日期
    ORDER BY event_time
),
max_online AS (
    -- 获取当日最大在线人数
    SELECT MAX(online_users) AS max_users FROM cumulative_users
)
-- 合并连续的峰值时间段
SELECT 
    MIN(event_time) AS busy_time_start,
    MAX(next_event_time) AS busy_time_end
FROM (
    SELECT 
        event_time,
        LEAD(event_time) OVER (ORDER BY event_time) AS next_event_time,
        online_users,
        -- 分组标记:在线人数从峰值下降时开启新组
        SUM(CASE WHEN online_users = (SELECT max_users FROM max_online) AND next_online_users = (SELECT max_users FROM max_online) THEN 0 ELSE 1 END) OVER (ORDER BY event_time) AS group_id
    FROM cumulative_users
    WHERE online_users = (SELECT max_users FROM max_online)
) t
GROUP BY group_id
ORDER BY busy_time_start;

结果说明

针对提供的测试数据,执行后会输出:

busy_time_start      | busy_time_end
--------------------------------------------
2022-09-10 04:10:00 | 2022-09-10 05:59:00
2022-09-10 06:05:00 | 2022-09-10 08:59:00

(注:原示例中的2022-09-10T03:10:00Z为误差,实际测试数据中04:10后才达到5人在线的峰值)


ClickHouse 效率对比

如果数据量达到百万级以上,迁移到ClickHouse会显著提升查询效率:

  1. 列式存储与并行计算:ClickHouse针对分析场景优化,能快速处理大规模时间序列数据;
  2. 原生区间聚合支持:可通过intervalJoin或事件拆分法高效计算区间重叠数,性能远优于MySQL;
  3. 低延迟响应:适合实时/准实时的在线人数峰值分析场景。

ClickHouse 示例查询

WITH event_points AS (
    SELECT enter_time AS event_time, 1 AS user_change FROM user_log
    UNION ALL
    SELECT leave_time AS event_time, -1 AS user_change FROM user_log
),
cumulative_users AS (
    SELECT 
        event_time,
        sum(user_change) OVER (ORDER BY event_time) AS online_users,
        lead(sum(user_change) OVER (ORDER BY event_time)) OVER (ORDER BY event_time) AS next_online_users
    FROM event_points
    WHERE toDate(event_time) = '2022-09-10'
    ORDER BY event_time
),
max_online AS (
    SELECT max(online_users) AS max_users FROM cumulative_users
)
SELECT 
    min(event_time) AS busy_time_start,
    max(next_event_time) AS busy_time_end
FROM (
    SELECT 
        event_time,
        lead(event_time) OVER (ORDER BY event_time) AS next_event_time,
        online_users,
        sumIf(1, online_users = max_users AND next_online_users != max_users) OVER (ORDER BY event_time) AS group_id
    FROM cumulative_users, max_online
    WHERE online_users = max_users
)
GROUP BY group_id
ORDER BY busy_time_start;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:45:42