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

如何将新增的查询占比列合并至单行统计结果集?

如何将新增统计列合并到原SQL的单行结果集?

原SQL用于从entrypoint_sql_queries表获取过去1小时的各类统计数据,现在需要新增一列——统计查询量最高的entrypoint的查询占比,对应的子查询已经写出,以下是几种合并到原单行结果集的方法:

方法1:将子查询作为标量子查询嵌入SELECT列表

这是最直接的方式,因为新增的子查询返回单行单列的结果,可以直接作为原查询的一个列字段:

SELECT COUNT(1)                                                            batch_count,
       ROUND(MAX(batch_duration_milliseconds) / 1000)                      max_batch_duration_seconds,
       ROUND(AVG(batch_duration_milliseconds) / 1000)                      avg_batch_duration_seconds,
       ROUND(MIN(batch_duration_milliseconds) / 1000, 1)                   min_batch_duration_seconds,
       ROUND(SUM(total_queries_duration_milliseconds) / SUM(batch_duration_milliseconds) *
             100)                                                          query_duration_percentage,
       SUM(total_queries)                                                  queries,
       ROUND(SUM(monitoring_queries) / SUM(total_queries) * 100)           percent_monitoring_queries,
       ROUND(SUM(total_queries) / SUM(batch_duration_milliseconds) * 1000) queries_per_second,
       MAX(max_query_duration_milliseconds)                                max_query_duration,
       ROUND(AVG(avg_query_duration_milliseconds))                         avg_query_duration,

       ROUND(SUM(retrieved_data_bytes) / 1024 / 1024)                      data_mb,
       ROUND(MAX(retrieved_data_bytes) / 1024 / 1024)                      max_batch_data_mb,
       ROUND(ROUND(AVG(retrieved_data_bytes)) / 1024 / 1024)               avg_batch_data_mb,
       ROUND(SUM(retrieved_data_bytes_calculation_duration_milliseconds) / SUM(batch_duration_milliseconds) *
             100, 1)                                                       percent_data_calc_duration,
       -- 新增的统计列:查询量最高的entrypoint的查询占比
       (SELECT ROUND(MAX(total_queries) / SUM(total_queries) * 100)
        FROM (
                 SELECT SUM(total_queries) AS total_queries
                 FROM entrypoint_sql_queries
                 WHERE created_at > SUBDATE(NOW(), INTERVAL 1 HOUR)
                 GROUP BY entrypoint
             ) as t) AS percent_most_expensive_job_queries
FROM entrypoint_sql_queries
WHERE created_at > SUBDATE(NOW(), INTERVAL 1 HOUR);

方法2:用CROSS JOIN合并两个单行结果

因为原查询和新增子查询都只返回一行数据,用CROSS JOIN可以直接把两个结果集的列合并成一行:

SELECT main.*, sub.percent_most_expensive_job_queries
FROM (
    -- 原统计查询
    SELECT COUNT(1)                                                            batch_count,
           ROUND(MAX(batch_duration_milliseconds) / 1000)                      max_batch_duration_seconds,
           ROUND(AVG(batch_duration_milliseconds) / 1000)                      avg_batch_duration_seconds,
           ROUND(MIN(batch_duration_milliseconds) / 1000, 1)                   min_batch_duration_seconds,
           ROUND(SUM(total_queries_duration_milliseconds) / SUM(batch_duration_milliseconds) *
                 100)                                                          query_duration_percentage,
           SUM(total_queries)                                                  queries,
           ROUND(SUM(monitoring_queries) / SUM(total_queries) * 100)           percent_monitoring_queries,
           ROUND(SUM(total_queries) / SUM(batch_duration_milliseconds) * 1000) queries_per_second,
           MAX(max_query_duration_milliseconds)                                max_query_duration,
           ROUND(AVG(avg_query_duration_milliseconds))                         avg_query_duration,

           ROUND(SUM(retrieved_data_bytes) / 1024 / 1024)                      data_mb,
           ROUND(MAX(retrieved_data_bytes) / 1024 / 1024)                      max_batch_data_mb,
           ROUND(ROUND(AVG(retrieved_data_bytes)) / 1024 / 1024)               avg_batch_data_mb,
           ROUND(SUM(retrieved_data_bytes_calculation_duration_milliseconds) / SUM(batch_duration_milliseconds) *
                 100, 1)                                                       percent_data_calc_duration
    FROM entrypoint_sql_queries
    WHERE created_at > SUBDATE(NOW(), INTERVAL 1 HOUR)
) AS main
CROSS JOIN (
    -- 新增的统计子查询
    SELECT ROUND(MAX(total_queries) / SUM(total_queries) * 100) percent_most_expensive_job_queries
    FROM (
             SELECT SUM(total_queries) AS total_queries
             FROM entrypoint_sql_queries
             WHERE created_at > SUBDATE(NOW(), INTERVAL 1 HOUR)
             GROUP BY entrypoint
         ) as t
) AS sub;

方法3:用窗口函数优化(减少表扫描次数)

上面两种方法会扫描表两次,用窗口函数可以只扫描一次表就完成所有统计,性能更优:

WITH entrypoint_totals AS (
    SELECT 
        entrypoint,
        SUM(total_queries) AS ep_total_queries,
        SUM(total_queries) OVER() AS global_total_queries,
        -- 计算当前entrypoint的查询量占比
        ROUND(SUM(total_queries) / SUM(total_queries) OVER() * 100) AS ep_percent,
        -- 原查询需要的全局统计字段
        COUNT(1) OVER() AS batch_count,
        ROUND(MAX(batch_duration_milliseconds) OVER() / 1000) AS max_batch_duration_seconds,
        ROUND(AVG(batch_duration_milliseconds) OVER() / 1000) AS avg_batch_duration_seconds,
        ROUND(MIN(batch_duration_milliseconds) OVER() / 1000, 1) AS min_batch_duration_seconds,
        ROUND(SUM(total_queries_duration_milliseconds) OVER() / SUM(batch_duration_milliseconds) OVER() * 100) AS query_duration_percentage,
        SUM(total_queries) OVER() AS queries,
        ROUND(SUM(monitoring_queries) OVER() / SUM(total_queries) OVER() * 100) AS percent_monitoring_queries,
        ROUND(SUM(total_queries) OVER() / SUM(batch_duration_milliseconds) OVER() * 1000) AS queries_per_second,
        MAX(max_query_duration_milliseconds) OVER() AS max_query_duration,
        ROUND(AVG(avg_query_duration_milliseconds) OVER()) AS avg_query_duration,
        ROUND(SUM(retrieved_data_bytes) OVER() / 1024 / 1024) AS data_mb,
        ROUND(MAX(retrieved_data_bytes) OVER() / 1024 / 1024) AS max_batch_data_mb,
        ROUND(ROUND(AVG(retrieved_data_bytes) OVER()) / 1024 / 1024) AS avg_batch_data_mb,
        ROUND(SUM(retrieved_data_bytes_calculation_duration_milliseconds) OVER() / SUM(batch_duration_milliseconds) OVER() * 100, 1) AS percent_data_calc_duration
    FROM entrypoint_sql_queries
    WHERE created_at > SUBDATE(NOW(), INTERVAL 1 HOUR)
    GROUP BY entrypoint, batch_duration_milliseconds, total_queries_duration_milliseconds, monitoring_queries, max_query_duration_milliseconds, avg_query_duration_milliseconds, retrieved_data_bytes, retrieved_data_bytes_calculation_duration_milliseconds
)
SELECT DISTINCT
    batch_count,
    max_batch_duration_seconds,
    avg_batch_duration_seconds,
    min_batch_duration_seconds,
    query_duration_percentage,
    queries,
    percent_monitoring_queries,
    queries_per_second,
    max_query_duration,
    avg_query_duration,
    data_mb,
    max_batch_data_mb,
    avg_batch_data_mb,
    percent_data_calc_duration,
    MAX(ep_percent) OVER() AS percent_most_expensive_job_queries
FROM entrypoint_totals;

这种方法通过窗口函数一次性计算所有全局统计和entrypoint级别的统计,最后取最高的占比,只需要扫描一次表,数据量大的时候优势明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:05:29