更新时间:2026-07-28 GMT+08:00
分享

路径生成

特性概述中所述,CBO阶段主要完成路径生成和计划选择,其与RBO阶段的主要差异在于RBO阶段的优化是基于SQL语句中的逻辑运算进行等价变换 ,而CBO阶段则是基于代价模型从生成的各种路径中选择出一棵“最好”的路径树(PathTree),这棵路径树中的每一条路径最终会映射成执行器能够具体执行的物理算子,而执行器正是通过执行这些物理算子来实现查询逻辑的。在GaussDB中这些物理算子可以大致分为两类:扫描路径和连接路径。

  • 扫描路径(ScanPath)

    扫描路径是指基表可以被遍历的方式,主要包括:顺序扫描路径(SeqScanPath)、索引扫描路径(IndexScanPath)、位图扫描路径(BitmapScanPath)等。以一个最基本的SQL语句为例:

    SELECT * FROM t1;

    其生成的执行计划如下:

                             QUERY PLAN
    -------------------------------------------------------------
     Streaming (type: GATHER)  (cost=0.12..2.27 rows=5 width=16)
       Node/s: All datanodes
       ->  Seq Scan on t1  (cost=0.00..2.02 rows=5 width=16)
    (3 rows)

    在该示例中“Seq Scan on t1”是由顺序扫描路径生成的。实际上,对于不同的SQL语句,根据约束条件、数据分布情况的不同优化器可以生成不同的扫描路径,详细说明可以参考扫描路径生成章节。

  • 连接路径(JoinPath)

    连接路径主要记录各类基表之间物理连接的方式,主要包括:NestloopJoinPath、HashJoinPath、MergeJoinPath等物理连接路径,详细说明可以参考连接路径生成章节。对于同一个SQL而言,不同连接方式都可以实现查询逻辑,但是选择不同连接路径的执行效率是不同的。以一个基本的InnerJoin场景为例,其SQL语句如下:

    SELECT * FROM t1 INNER JOIN t2 ON t1.b = t2.b;

    该示例可以生成HashJoin路径,其计划如下所示:

                                           QUERY PLAN
    -----------------------------------------------------------------------------------------
     Streaming (type: GATHER)  (cost=187.03..576.53 rows=5000 width=32)
       Node/s: All datanodes
       ->  Hash Join  (cost=183.03..368.15 rows=5000 width=32)
             Hash Cond: (t1.b = t2.b)
             ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..162.20 rows=5000 width=16)
                   Spawn on: All datanodes
                   ->  Seq Scan on t1  (cost=0.00..24.67 rows=5000 width=16)
             ->  Hash  (cost=162.20..162.20 rows=5001 width=16)
                   ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..162.20 rows=5000 width=16)
                         Spawn on: All datanodes
                         ->  Seq Scan on t2  (cost=0.00..24.67 rows=5000 width=16)
    (11 rows)

    也可以生成NestloopJoin路径,其计划如下所示:

                                           QUERY PLAN
    -----------------------------------------------------------------------------------------
     Streaming (type: GATHER)  (cost=4.00..42220.27 rows=5000 width=32)
       Node/s: All datanodes
       ->  Nested Loop  (cost=0.00..42011.90 rows=5000 width=32)
             Join Filter: (t1.b = t2.b)
             ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..162.20 rows=5000 width=16)
                   Spawn on: All datanodes
                   ->  Seq Scan on t1  (cost=0.00..24.67 rows=5000 width=16)
             ->  Materialize  (cost=0.00..170.53 rows=5000 width=16)
                   ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..162.20 rows=5000 width=16)
                         Spawn on: All datanodes
                         ->  Seq Scan on t2  (cost=0.00..24.67 rows=5000 width=16)
    (11 rows)

    从两个计划的代价可知,对于该场景HashJoin路径生成的计划执行性能要明显好于NestloopJoin路径计划。物理优化阶段的一个重要工作就是尝试生成不同的物理连接路径并从中选出代价最低的连接路径,从而提升查询计划的执行性能。

    此外,在优化器中实际进行选择路径时要考虑很多因素,比如根据磁盘类型、CPU参数等调整代价基准值,根据数据分布的统计信息、条件约束、选择率等评估基表扫描是选择索引扫描路径还是顺序扫描路径,以及对于路径的启动代价、整体代价如何选择,因而在路径生成阶段通常需要保留多条物理路径,在计划生成时通过代价估算模型进行决策。

相关文档