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

Redshift EXPLAIN执行计划解析与查询优化咨询

Redshift查询执行计划解析与优化问题

查询语句

SELECT
    (TO_CHAR(DATE_TRUNC('second', CONVERT_TIMEZONE('GMT', 'UTC', "ABC"."time")), 'YYYY-MM-DD HH24:MI:SS')) AS "rtime",
    COUNT(DISTINCT ABC.s) AS "s"
FROM
    ABC
    INNER JOIN TE ON "ABC"."e_id" = "TE"."e_id"
WHERE "TE"."e_code" = 'ABCDE'
GROUP by 1 
ORDER BY 1

执行计划

XN Merge  (cost=1000000944628.86..1000000944629.36 rows=200 width=200)
  Merge Key: resp
  ->  XN Network  (cost=1000000944628.86..1000000944629.36 rows=200 width=200)
        Send to leader
        ->  XN Sort  (cost=1000000944628.86..1000000944629.36 rows=200 width=200)
              Sort Key: resp
              ->  XN HashAggregate  (cost=944620.71..944621.21 rows=200 width=200)
                    ->  XN Subquery Scan volt_dt_0  (cost=944506.75..944606.47 rows=2849 width=200)
                          ->  XN HashAggregate  (cost=944506.75..944577.98 rows=2849 width=29)
                                ->  XN Hash Join DS_DIST_ALL_NONE  (cost=132.60..944492.51 rows=2849 width=29)
                                      Hash Cond: (((("outer".context_id)::text || ':'::text) || ("outer".e_id)::text) = ("inner".e_id)::text)
                                      ->  XN Seq Scan on ABC (cost=0.00..151081.63 rows=15108163 width=33)
                                      ->  XN Hash  (cost=132.60..132.60 rows=2 width=17)
                                            ->  XN Seq Scan on te  (cost=0.00..132.60 rows=2 width=17)
                                                  Filter: ((e_code)::text = 'ABCDE'::text)

表结构配置

  • ABC表:
DISTSTYLE EVEN
SORTKEY ( inserted_datetime );
  • TE表:
DISTSTYLE ALL
SORTKEY ( e_id );

问题解答

1. 是ORDER子句还是Sequence Scan导致性能问题?

主要性能瓶颈是ABC表的全表扫描(Seq Scan):ABC表有1500多万行数据,全表扫描需要遍历所有节点上的该表数据,这是40秒耗时的核心来源。而ORDER BY对应的排序操作仅针对最终200行结果,实际耗时可以忽略,执行计划中高cost是因为叠加了数据传输到leader节点的估算开销,并非实际排序的耗时。

解决Seq Scan的方案:

  • 调整ABC表的排序键,添加e_id作为前缀(比如SORTKEY (e_id, inserted_datetime)),这样可以利用排序键的前缀过滤,只扫描与TE表匹配的e_id对应的数据块,减少扫描量;
  • 如果业务允许,将ABC表的分布键改为e_id,避免关联时的数据跨节点传输,但需评估对其他查询的影响;
  • 确保表统计信息是最新的,执行ANALYZE ABC;让优化器生成更准确的执行计划。

2. 是否可以认为cost值越高,执行时间越长?

不完全是。Redshift的cost是基于统计信息的估算值,不是实际执行时间的精确映射:

  • 执行计划中XN Merge和XN Sort的cost最高,但处理的仅为200行数据,实际耗时极低;
  • ABC表的Seq Scan cost看似低,但处理1500多万行数据,实际耗时占比最高。
    判断性能瓶颈需结合rows列显示的实际处理行数,而非仅看cost值。

3. 为何使用'XN Hash Join DS_DIST_ALL_NONE'而非EVEN分布风格?

DS_DIST_ALL_NONE是Redshift根据两表分布策略选择的最优连接方式:

  • TE表是DISTSTYLE ALL,每个计算节点都有完整的TE表副本;
  • ABC表是DISTSTYLE EVEN,数据均匀分布在各节点;
    这种情况下,每个节点可以直接用本地的TE副本与本地的ABC数据做哈希连接,无需移动任何表的数据,DS_DIST_ALL_NONE正是描述这种“无需重分布”的连接策略,和两表的分布风格直接相关。

4. 为何此处使用Subquery Scan?

这是Redshift优化器的内部实现细节:因为查询使用了COUNT(DISTINCT ABC.s),优化器会先执行一次HashAggregate完成去重计算,生成中间结果集;Subquery Scan volt_dt_0就是用来临时扫描这个中间结果集的步骤,为外层的最终聚合做准备,属于优化器自动生成的逻辑,不需要手动调整。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:25:19