3.5.10集群,sql查询慢

为了更快的定位您的问题,请提供以下信息,谢谢
【详述】SELECT t0.exp_id AS exp_id, t0.grp_id AS grp_id, COVAR_SAMP(COALESCE(t0.zi, 0), COALESCE(t0.zi, 0)) AS abt_100011576_var_zi, COVAR_SAMP(COALESCE(t0.mu, 0), COALESCE(t0.mu, 0)) AS abt_100011576_var_mu, COVAR_SAMP(COALESCE(t0.zi, 0), COALESCE(t0.mu, 0)) AS abt_100011576_cov_zi_mu, COVAR_SAMP(COALESCE(t0.zi, 0), COALESCE(t1.uv, 0)) AS abt_100011576_cov_zi_uv, COVAR_SAMP(COALESCE(t0.mu, 0), COALESCE(t1.uv, 0)) AS abt_100011576_cov_mu_uv, COVAR_SAMP(COALESCE(t1.uv, 0), COALESCE(t1.uv, 0)) AS abt_100011576_var_uv, SUM(t0.zi) AS abt_100011576_sum_zi, SUM(t0.mu) AS abt_100011576_sum_mu, SUM(t1.uv) AS abt_100011576_sum_uv, SUM(t0.zi) / SUM(t0.mu) AS abt_100011576, COUNT(1) AS abt_100011576_bucket_num FROM(SELECT exp_id, grp_id, bucket_id, SUM(search_ymal_gmv) AS zi, SUM(search_eps_goods_num) AS mu FROM dm.dm_abt_exp_grp_bucket_search_top_source_trigger_1d WHERE exp_id = 100791211 AND grp_id IN (102059666, 102059661) AND dt BETWEEN ‘20260122’ AND ‘20260127’ GROUP BY exp_id, grp_id, bucket_id) AS t0 INNER JOIN (SELECT exp_id, grp_id, bucket_id, COUNT(DISTINCT user_sl_id) AS uv FROM dm.dm_abt_user_siteid_lang_detail_1d WHERE exp_id = 100791211 AND grp_id IN (102059666, 102059661) AND dt BETWEEN ‘20260122’ AND ‘20260127’ GROUP BY exp_id, grp_id, bucket_id) AS t1 ON t1.exp_id = t0.exp_id AND t1.grp_id = t0.grp_id AND t1.bucket_id = t0.bucket_id GROUP BY t0.exp_id, t0.grp_id;
上面的sql执行时间为6~7s,预计毫秒级
【背景】做过哪些操作?
TRACE TIMES OPTIMIZER后发现,主要耗时在CBO期间image
【业务影响】
【是否存算分离】是
【StarRocks版本】3.5.10
【集群规模】例如:3fe(1 follower+2observer)+30be(fe与be混部)
【机器信息】fe 64C512G,be 32C256G
【联系方式】为了在解决问题过程中能及时联系到您获取一些日志信息,请补充下您的联系方式,例如:社区群4-小李或者邮箱,谢谢
【附件】

  • fe.log/beINFO/相应截图
  • 慢查询:
    • Profile信息
    • 并行度:show variables like ‘%parallel_fragment_exec_instance_num%’;
    • pipeline是否开启:show variables like ‘%pipeline%’;
    • be节点cpu和内存使用率截图
  • 查询报错:
  • be crash
    • be.out
  • 外表查询报错
    • be.out和fe.warn.log

您提供的 SQL 语句是一个复杂的查询,包含了两个子查询 (t0t1)、一个 INNER JOIN、多个聚合函数(包括多个 COVAR_SAMPSUMCOUNT)以及最终的 GROUP BY

问题核心: SQL 执行时间 6~7 秒,但 TRACE TIMES OPTIMIZER 显示主要耗时在 CBO(基于成本的优化器) 阶段。

CBO 耗时过长通常由以下几个原因引起:

  1. 查询复杂度高: 您的查询结构复杂,包含多个子查询、连接和大量的聚合计算(尤其是 COVAR_SAMP 需要处理大量数据)。CBO 需要评估大量的连接顺序、物化点、聚合策略等,这会增加优化时间。
  2. 统计信息缺失或不准确: CBO 依赖表的统计信息来准确估算中间结果集的大小(Cardinality Estimation,CE)。如果统计信息缺失、过期或不准确,CBO 可能需要探索更多的执行路径,或者在某些复杂计算(如连接和聚合)上花费更多时间进行预估。
  3. CBO 优化规则过多或配置问题: 某些高级优化规则在处理复杂查询时可能会显著增加优化时间。
  4. 数据量过大(但您提到耗时在 CBO 阶段,因此数据执行时间可能不是主要瓶颈): 如果子查询返回的结果集非常大,CBO 在处理连接和聚合时,虽然理论上是在优化阶段,但其内部的估算逻辑可能会被大数据量拖慢。

解决方案和排查步骤

为了将 CBO 耗时从秒级降低到毫秒级,您可以尝试以下方法:

1. 检查和更新统计信息(最重要)

CBO 的效率和准确性严重依赖统计信息。如果统计信息不准确,CBO 可能会评估错误的执行计划或花费大量时间在不必要的路径探索上。

操作:

  1. 检查统计信息状态:

    SHOW ANALYZE STATUS;
    -- 或
    SHOW STATS HEALTH ON dm.dm_abt_exp_grp_bucket_search_top_source_trigger_1d;
    SHOW STATS HEALTH ON dm.dm_abt_user_siteid_lang_detail_1d;
    

    确认涉及的表 (dm.dm_abt_exp_grp_bucket_search_top_source_trigger_1ddm.dm_abt_user_siteid_lang_detail_1d) 的统计信息是否健康(Health 值是否接近 100)。

  2. 手动触发全量统计信息收集(如果健康度低):

    ANALYZE TABLE dm.dm_abt_exp_grp_bucket_search_top_source_trigger_1d WITH SYNC;
    ANALYZE TABLE dm.dm_abt_user_siteid_lang_detail_1d WITH SYNC;
    

    收集完成后,再次执行 SQL 观察 CBO 耗时是否有改善。

2. 简化查询结构(如果可能)

复杂的子查询和多重聚合是 CBO 耗时的主要原因。

尝试优化 SQL 结构:

您的查询本质上是将两个子查询的结果连接起来,然后进行最终聚合。如果两个子查询的 Group By 键完全相同,可以考虑使用 CTE (Common Table Expressions) 或视图来提高可读性,虽然对 CBO 性能的直接影响不一定大,但有时能帮助 CBO 更好地识别公共表达式。

WITH t0 AS (
    SELECT exp_id, grp_id, bucket_id, SUM(search_ymal_gmv) AS zi, SUM(search_eps_goods_num) AS mu 
    FROM dm.dm_abt_exp_grp_bucket_search_top_source_trigger_1d 
    WHERE exp_id = 100791211 AND grp_id IN (102059666, 102059661) AND dt BETWEEN '20260122' AND '20260127' 
    GROUP BY exp_id, grp_id, bucket_id
),
t1 AS (
    SELECT exp_id, grp_id, bucket_id, COUNT(DISTINCT user_sl_id) AS uv 
    FROM dm.dm_abt_user_siteid_lang_detail_1d 
    WHERE exp_id = 100791211 AND grp_id IN (102059666, 102059661) AND dt BETWEEN '20260122' AND '20260127' 
    GROUP BY exp_id, grp_id, bucket_id
)
SELECT 
    t0.exp_id AS exp_id, 
    t0.grp_id AS grp_id, 
    -- ... 聚合函数
    COVAR_SAMP(COALESCE(t0.zi, 0), COALESCE(t0.zi, 0)) AS abt_100011576_var_zi, 
    -- ... 其他 COVAR_SAMP, SUM, COUNT
    SUM(t0.zi) / SUM(t0.mu) AS abt_100011576, 
    COUNT(1) AS abt_100011576_bucket_num 
FROM t0 
INNER JOIN t1 ON t1.exp_id = t0.exp_id AND t1.grp_id = t0.grp_id AND t1.bucket_id = t0.bucket_id 
GROUP BY t0.exp_id, t0.grp_id;

3. 调整 CBO 优化器超时时间或配置

如果 CBO 尝试的优化路径过多,可能会触发内部超时,或者仅仅是耗时过长。您可以尝试调整会话变量来限制或优化 CBO 的行为。

  • 查看 CBO 规则: 复杂的优化规则,如 RBO 之后的 CBO 连接顺序选择,是耗时主要来源。

  • 尝试关闭部分高级优化(仅用于测试): 某些情况下,关闭一些耗时的优化规则可以加速 CBO 阶段,尽管可能牺牲最终执行计划的质量。

  • 增加 CBO 优化器的超时时间(如果 CBO 失败): 如果 CBO 超时,它会返回一个次优的计划。但您的描述是耗时 6~7s,这表明 CBO 正在努力工作。

建议尝试的会话变量:

如果您的 StarRocks 版本支持,可以尝试调整 CBO 的探索深度或超时:

-- 增加 CBO 超时,确保它能完成优化 (如果优化失败,可能更快)
SET query_timeout = 600; -- 确认查询执行时间足够长

-- 尝试关闭 CBO,退回到 RBO (不推荐,但可测试是否为 CBO 独有问题)
SET enable_cost_based_optimizer = false; 
-- 如果关闭 CBO 后执行时间大幅缩短,则确认是 CBO 自身的问题。

4. 检查数据倾斜和 Join 键

虽然 CBO 阶段的耗时与数据执行耗时是分开的,但如果 CBO 估算发现连接或聚合操作存在严重数据倾斜(例如,bucket_id 的分布非常不均匀),它可能会花费额外时间来尝试寻找倾斜处理的优化方案。

  • 检查 exp_id, grp_id, bucket_id 组合的基数(Cardinality)。如果子查询的结果集基数很高,CBO 的复杂度会呈指数级增长。

总结:

在您的场景中,最有可能的原因是 CBO 在处理复杂的 Join 和聚合时,由于统计信息的不准确或缺失,导致它必须探索过多的执行路径。

首要且最有效的措施是: 立即检查并更新涉及的两个大表的统计信息。 如果更新统计信息后问题仍未解决,请使用 EXPLAIN COSTS 语句查看 CBO 的成本估算结果,并考虑联系 StarRocks 社区寻求针对 3.1.11 版本的 CBO 性能调优建议。