研究了GPORCA优化器的优化步骤、优化原理、工程实现方法
简介
GPORCA是GreenPlum中的全新模块化查询优化器,代替了传统的Planner优化器,在OLAP查询优化性能上有了明显的进步。在TPC-DS测试中,大部分场景均有提高。基于GPORCA+Hadoop的HAWQ优化器,在测试中完胜Impala和Stinger优化器。
GPORCA优化器在设计上源于Cascades Framework模型。
GPORCA优化器的性能提升情况如下图:
架构
GPORCA的系统边界如下图所示,最下方为GPORCA优化器,上方为数据库系统。
GPORCA接受数据库系统输入的查询语句(Query)和元数据(MataData,MD),并输出物理执行计划(Plan)。Query/MD/Plan均为DLX格式。
DXL 格式示例请见文章末尾
GPORCA 内部结构如下图,分为Job执行、Job编排、Memo、GPOS等部分
-
Memo: 记录搜索路径:
- Memo保存所有可能的计划
- 每个Memo Group保存所有的等效Expression
- 物理计划也是直接使用Memo,且代价是计算物理计划的代价
-
Search: 代表3类Job
- exploration:逻辑上扩充Memo,搜索可能的逻辑计划
- implementation:将逻辑计划转换为物理计划
- optimization:根据需求的输出参数,增加Enforcer Expression,计算代价
Job Scheduler:规划并执行Job
-
Transformations:Memo的转换规则,有两大类:
- 逻辑计划 > 逻辑计划: 用于exploration job
- 逻辑计划 > 物理计划: 用于implementation job
-
Property Enforcement:数据参数增强
- 对每个算子的输出参数,进行描述
- 算子输出不满足要求的,增加Enforcer,额外处理数据。
Metadata Cache:元数据缓存
GPOS:底层库,处理IO、异常、内存、并发等
优化执行顺序
- 示例SQL语句:
SELECT
T1.a
FROM
T1,
T2
WHERE
T1.a = T2.b
ORDER BY
T1.a;
- 初始Memo:
步骤1:逻辑计划探索(Exploration)
利用所有逻辑Transformation对每个Memo组进行检查扩充,或者增加新的Memo组。例如,使用 CJoinOrder
Transformation,可以发现InnerJoin[2,1]
与 InnerJoin[1,2]
在逻辑上等价,则将 InnerJoin[2,1]
加入到 GROUP0。
使用上述方法,对每个Memo Group的每个Expression应用Transformation,完成逻辑Memo的构建:
步骤2:统计信息推算(Statistics Derivation)
逻辑Memo构建完成后,进行统计信息推算。
- 首先,针对同一GROUP,选取推算输出统计信息最可靠的Expression。
- 从顶向下请求统计信息
- 从低向上推算统计信息
- 统计信息可以在推算中进行增量更新
步骤3:逻辑计划转物理计划(Implementation)
使用逻辑计划 > 物理计划的Transformation,将逻辑Memo转为物理Memo,例如:
-
Get2Scan
这个Transform将逻辑Get
转换为物理Scan
-
InnerJoin[1,2]
被转换为Inner NLJoin [1,2]
和Inner HashJoin [1,2]
转换完成后的Memo:
步骤4:优化(Optimization)
这一步对物理计划进行完善(enforce),并计算代价
Add Enforcer
- 从顶至下发送优化请求(
optimization request
),优化请求包含:输出列、输出order、输出数据分布等 - 每个Expression收到优化请求,先根据
optimization request
为给自己增加Enforcer,Enforcer本身还可以增加Enforcer - Enforcer增加完成后,Memo结构如下:
代价计算
- 从底至上计算每个算子的代价,选出针对每个
optimization request
的最优代价算子 - 代价计算完成后,Memo结构如下:
执行计划导出
- 从顶端开始,导出最优执行计划
- 每个算子内部有HashTable,标明为了完成
optimization request
,他的子算子需要满足的optimization request
- 以下图为例,为了满足查询语句最顶层的1号or,最优算子是GROUP0的8号算子,为了满足1号or),8号算子需要3号or。3号or的最优算子是6号算子,6号算子为了满足3号or,需要4号or。4号or的最优算子是4号算子。4号算子为了满足4号or,需要7、10号or。继续跟踪7、10号or,即可顶端向下导出完整执行计划。
Job 调度
为了更好的完成上述的优化过程,并实现并行优化能力,GPORCA根据Cascades架构设计了Job 调度系统。
Job注册
在job注册阶段,GPORCA对注册7类job:
- Exp(g):针对单个Memo组,做逻辑路径探索(Exploration)
- Exp(gexpr):针对单个Memo中单个算子(Expression),做逻辑路径探索(Exploration)
- Imp(g):针对单个Memo组,做逻辑计划转物理计划(Implementation)
- Imp(gexpr): 针对单个Memo中单个算子(Expression),做逻辑计划转物理计划(Implementation)
- Opt(g, req):针对单个Memo组,做优化(Optimization)
- Opt(gexpr, req):针对单个Memo中单个算子(Expression),做优化(Optimization)
- Xform(gexpr, t):针对单个Memo中单个算子(Expression),做变换(Transformation)
各种Job的依赖关系如下:
job执行
所有job注册完成后,进入执行阶段:
- job架构不断从job队列中取出job
- 检查其子job是否全部执行完成,若可以执行,则调用job对应的方法
- 若子job未全部执行完成,则将job放回队列,等待下次执行
计划的执行
GPORCA 只负责生成计划,并不执行计划,计划会发送到GreenPlum节点执行,计划的执行已经超出本文讨论的范围。但是因为GreenPlum执行方式有其特殊性,而且GPORCA的优化原理与GreenPlum执行原理耦合较深,这里简要介绍一下GreenPlum的执行机制。
Slice 和 Gang
Greenplum 数据库在查询执行过程中,为了增加查询执行的并行度,会将查询计划切分成多个Slice。每一个Slice可以视为单机可执行的查询计划片段,其所对应的数据或者是本地数据,或者是通过计划树下层Motion节点传递过来的数据。所以,在Greenplum并行查询计划中,每一个Motion节点都会生成一个Slice,每一个Slice由一个进程来执行对应此部分的查询计划。通过Slice将查询计划并行化,既可加快查询执行速度,又可以充分提高系统CPU等资源的利用率。
在 Greenplum 并行查询计划中,每个 Motion 节点均有两个属性:sliceld 和 segments。sliceld 是这个 Slice 在并行查询计划里的唯一标识。 segments 是参与执行该 Slice 的 Segment实例数量, 要么是 l,对应 Master 节点;要么是N, 对应整个 Greenplum 集群中 Segment 实例总数。
所有 Segment 实例上执行同一 Sliceld 操作的一组进程称为一个 Gang。 在一个规模为N 的 Greenplum 集群中, Gang 的大小或者是N (N-Gang), 或是 1 (1-Gang)。 N-Gang 通常对 应运行在 Segment 实例上的普通操作。 例如,在N个 Segment 实例上,每个 Segment 启动一个进程执行全表扫描操作。1-Gang 通常对应运行在 Master 节点上的 Gather Motion, 启动 一个进程收集所有 Segment 上的数据进行汇总。Gang 的大小即为查询的并行度。
如图:此并行查询计划分为4个Slice, Root Slice(Slice0)运行在Master节点上,其余Slice均运行在Segment上,执行每个非Root Slice的进程数为Segment实例数。
在有 3 个Segment 实例的 Greenplum 集群中,根据 Slice 分配 Gang 的结果如图:
调度与执行
为了执行计划,GreenPlum有调度器(QueryDispatcher, QD)和执行器(QueryExecutor, QE):
调度器(QueryDispatcher, QD):将查询计 划发送给所有Segment节点上的执行器,待执行器执行完查询任务后,收集所有执行器的 查询结果,汇总后返回给客户端。调度器在查询执行过程中,主要负责执行器的创建、销毁、错误处理、任务取消、状态更新等。
执行器(QueryExecutor, QE)收到调度器发送的查询计划后, 就执行查询计划中自己所负责的那个部分。 典型的操作包括表扫描、 哈希关联、 排序、 聚集等。
GPORCA代码结构
总体结构
.
├── cmake //编译,构建
├── concourse //CICD
├── data //测试数据集
├── libgpdbcost //gpdbcost包
├── libgpopt //gpopt包
├── libgpos //gpos包
├── libnaucrates //naucrates包
├── patches //补丁
├── scripts //单元测试
└── server //单元测试
gpos包
- gpos包是底层库,负责管理内存、处理异常、单元测试架构等
libgpos
├── include
└── src
├── common
├── error
├── io
├── memory
├── net
├── string
├── sync
├── task
└── test
naucrates包
- naucrates包处理DXL数据结构、元数据、统计信息、特性控制
libnaucrates
├── include
│ └── naucrates
│ ├── base
│ ├── dxl
│ │ ├── operators
│ │ ├── parser
│ │ └── xml
│ ├── md
│ ├── statistics
│ └── traceflags
└── src
├── base
├── md
├── operators
├── parser
├── statistics
└── xml
libgpopt
- 优化引擎、元数据缓存、算子定义、memo、xform规则
libgpopt
├── include
│ └── gpopt
└── src
├── base
├── engine
├── eval
├── mdcache
├── metadata
├── minidump
├── operators
├── optimizer
├── search
├── translate
└── xforms
libgpdbcost
- 代价模型
libgpdbcost
├── CMakeLists.txt
├── include
│ └── gpdbcost
└── src
├── CCostModelGPDB.cpp
├── CCostModelGPDBLegacy.cpp
├── CCostModelParamsGPDB.cpp
├── CCostModelParamsGPDBLegacy.cpp
└── ICostModel.cpp
关键代码
- CEngine::Optimize 优化引擎入口
- search包:Job定义
- search包中的每个Job类型文件,均有状态转移图,标识了优化的各个阶段,会使用哪些job
- CCostModelGPDB:代价模型,所有物理算子的代价计算方法
- CCostModelParamsGPDB:代价参数,所有代价模型的具体代价参数
相关资料
Youtube - Understanding the internals of GPORCA Optimizer
DXL 格式示例
MD
<dxl:Metadata SystemIds="0.GPDB">
<dxl:ColumnStatistics Mdid="1.4015159.1.1.0" Name="b" Width="8.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false" />
<dxl:Type Mdid="0.16.1.0" Name="bool" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="1" PassByValue="true">
<dxl:EqualityOp Mdid="0.91.1.0" />
<dxl:InequalityOp Mdid="0.85.1.0" />
<dxl:LessThanOp Mdid="0.58.1.0" />
<dxl:LessThanEqualsOp Mdid="0.1694.1.0" />
<dxl:GreaterThanOp Mdid="0.59.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.1695.1.0" />
<dxl:ComparisonOp Mdid="0.1693.1.0" />
<dxl:ArrayType Mdid="0.1000.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.1043.1.0" Name="varchar" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="true" IsFixedLength="false" Length="-1" PassByValue="false">
<dxl:EqualityOp Mdid="0.98.1.0" />
<dxl:InequalityOp Mdid="0.531.1.0" />
<dxl:LessThanOp Mdid="0.664.1.0" />
<dxl:LessThanEqualsOp Mdid="0.665.1.0" />
<dxl:GreaterThanOp Mdid="0.666.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.667.1.0" />
<dxl:ComparisonOp Mdid="0.360.1.0" />
<dxl:ArrayType Mdid="0.1015.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.23.1.0" Name="int4" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.96.1.0" />
<dxl:InequalityOp Mdid="0.518.1.0" />
<dxl:LessThanOp Mdid="0.97.1.0" />
<dxl:LessThanEqualsOp Mdid="0.523.1.0" />
<dxl:GreaterThanOp Mdid="0.521.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.525.1.0" />
<dxl:ComparisonOp Mdid="0.351.1.0" />
<dxl:ArrayType Mdid="0.1007.1.0" />
<dxl:MinAgg Mdid="0.2132.1.0" />
<dxl:MaxAgg Mdid="0.2116.1.0" />
<dxl:AvgAgg Mdid="0.2101.1.0" />
<dxl:SumAgg Mdid="0.2108.1.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.25.1.0" Name="text" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="true" IsFixedLength="false" Length="-1" PassByValue="false">
<dxl:EqualityOp Mdid="0.98.1.0" />
<dxl:InequalityOp Mdid="0.531.1.0" />
<dxl:LessThanOp Mdid="0.664.1.0" />
<dxl:LessThanEqualsOp Mdid="0.665.1.0" />
<dxl:GreaterThanOp Mdid="0.666.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.667.1.0" />
<dxl:ComparisonOp Mdid="0.360.1.0" />
<dxl:ArrayType Mdid="0.1009.1.0" />
<dxl:MinAgg Mdid="0.2145.1.0" />
<dxl:MaxAgg Mdid="0.2129.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.26.1.0" Name="oid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.607.1.0" />
<dxl:InequalityOp Mdid="0.608.1.0" />
<dxl:LessThanOp Mdid="0.609.1.0" />
<dxl:LessThanEqualsOp Mdid="0.611.1.0" />
<dxl:GreaterThanOp Mdid="0.610.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.612.1.0" />
<dxl:ComparisonOp Mdid="0.356.1.0" />
<dxl:ArrayType Mdid="0.1028.1.0" />
<dxl:MinAgg Mdid="0.2118.1.0" />
<dxl:MaxAgg Mdid="0.2134.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.27.1.0" Name="tid" IsRedistributable="true" IsHashable="false" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="6" PassByValue="false">
<dxl:EqualityOp Mdid="0.387.1.0" />
<dxl:InequalityOp Mdid="0.402.1.0" />
<dxl:LessThanOp Mdid="0.2799.1.0" />
<dxl:LessThanEqualsOp Mdid="0.2801.1.0" />
<dxl:GreaterThanOp Mdid="0.2800.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.2802.1.0" />
<dxl:ComparisonOp Mdid="0.2794.1.0" />
<dxl:ArrayType Mdid="0.1010.1.0" />
<dxl:MinAgg Mdid="0.2798.1.0" />
<dxl:MaxAgg Mdid="0.2797.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.29.1.0" Name="cid" IsRedistributable="false" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.385.1.0" />
<dxl:InequalityOp Mdid="0.0.0.0" />
<dxl:LessThanOp Mdid="0.0.0.0" />
<dxl:LessThanEqualsOp Mdid="0.0.0.0" />
<dxl:GreaterThanOp Mdid="0.0.0.0" />
<dxl:GreaterThanEqualsOp Mdid="0.0.0.0" />
<dxl:ComparisonOp Mdid="0.0.0.0" />
<dxl:ArrayType Mdid="0.1012.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.28.1.0" Name="xid" IsRedistributable="false" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.352.1.0" />
<dxl:InequalityOp Mdid="0.0.0.0" />
<dxl:LessThanOp Mdid="0.0.0.0" />
<dxl:LessThanEqualsOp Mdid="0.0.0.0" />
<dxl:GreaterThanOp Mdid="0.0.0.0" />
<dxl:GreaterThanEqualsOp Mdid="0.0.0.0" />
<dxl:ComparisonOp Mdid="0.0.0.0" />
<dxl:ArrayType Mdid="0.1011.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:MDCast Mdid="3.25.1.0;25.1.0" Name="text" BinaryCoercible="true" SourceTypeId="0.25.1.0" DestinationTypeId="0.25.1.0" CastFuncId="0.0.0.0" CoercePathType="0" />
<dxl:MDCast Mdid="3.1043.1.0;25.1.0" Name="text" BinaryCoercible="true" SourceTypeId="0.1043.1.0" DestinationTypeId="0.25.1.0" CastFuncId="0.0.0.0" CoercePathType="0" />
<dxl:RelationStatistics Mdid="2.4015133.1.1" Name="foo" Rows="0.000000" EmptyRelation="true" />
<dxl:Relation Mdid="0.4015133.1.1" Name="foo" IsTemporary="false" HasOids="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="7,1" NumberLeafPartitions="0">
<dxl:Columns>
<dxl:Column Name="a" Attno="1" Mdid="0.1043.1.0" Nullable="true" ColWidth="16">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="ctid" Attno="-1" Mdid="0.27.1.0" Nullable="false" ColWidth="6">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmin" Attno="-3" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmin" Attno="-4" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmax" Attno="-5" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmax" Attno="-6" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="tableoid" Attno="-7" Mdid="0.26.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="gp_segment_id" Attno="-8" Mdid="0.23.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
</dxl:Columns>
<dxl:IndexInfoList />
<dxl:Triggers />
<dxl:CheckConstraints />
</dxl:Relation>
<dxl:ColumnStatistics Mdid="1.4015133.1.1.0" Name="a" Width="8.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false" />
<dxl:GPDBScalarOp Mdid="0.98.1.0" Name="=" ComparisonType="Eq" ReturnsNullOnNullInput="false" IsNDVPreserving="false">
<dxl:LeftType Mdid="0.25.1.0" />
<dxl:RightType Mdid="0.25.1.0" />
<dxl:ResultType Mdid="0.16.1.0" />
<dxl:OpFunc Mdid="0.67.1.0" />
<dxl:Commutator Mdid="0.98.1.0" />
<dxl:InverseOp Mdid="0.531.1.0" />
</dxl:GPDBScalarOp>
<dxl:RelationStatistics Mdid="2.4015159.1.1" Name="bar" Rows="0.000000" EmptyRelation="true" />
<dxl:Relation Mdid="0.4015159.1.1" Name="bar" IsTemporary="false" HasOids="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="7,1" NumberLeafPartitions="0">
<dxl:Columns>
<dxl:Column Name="b" Attno="1" Mdid="0.1043.1.0" Nullable="true" ColWidth="16">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="ctid" Attno="-1" Mdid="0.27.1.0" Nullable="false" ColWidth="6">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmin" Attno="-3" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmin" Attno="-4" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmax" Attno="-5" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmax" Attno="-6" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="tableoid" Attno="-7" Mdid="0.26.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="gp_segment_id" Attno="-8" Mdid="0.23.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
</dxl:Columns>
<dxl:IndexInfoList />
<dxl:Triggers />
<dxl:CheckConstraints />
</dxl:Relation>
</dxl:Metadata>
Query
<dxl:Metadata SystemIds="0.GPDB">
<dxl:ColumnStatistics Mdid="1.4015159.1.1.0" Name="b" Width="8.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false" />
<dxl:Type Mdid="0.16.1.0" Name="bool" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="1" PassByValue="true">
<dxl:EqualityOp Mdid="0.91.1.0" />
<dxl:InequalityOp Mdid="0.85.1.0" />
<dxl:LessThanOp Mdid="0.58.1.0" />
<dxl:LessThanEqualsOp Mdid="0.1694.1.0" />
<dxl:GreaterThanOp Mdid="0.59.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.1695.1.0" />
<dxl:ComparisonOp Mdid="0.1693.1.0" />
<dxl:ArrayType Mdid="0.1000.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.1043.1.0" Name="varchar" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="true" IsFixedLength="false" Length="-1" PassByValue="false">
<dxl:EqualityOp Mdid="0.98.1.0" />
<dxl:InequalityOp Mdid="0.531.1.0" />
<dxl:LessThanOp Mdid="0.664.1.0" />
<dxl:LessThanEqualsOp Mdid="0.665.1.0" />
<dxl:GreaterThanOp Mdid="0.666.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.667.1.0" />
<dxl:ComparisonOp Mdid="0.360.1.0" />
<dxl:ArrayType Mdid="0.1015.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.23.1.0" Name="int4" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.96.1.0" />
<dxl:InequalityOp Mdid="0.518.1.0" />
<dxl:LessThanOp Mdid="0.97.1.0" />
<dxl:LessThanEqualsOp Mdid="0.523.1.0" />
<dxl:GreaterThanOp Mdid="0.521.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.525.1.0" />
<dxl:ComparisonOp Mdid="0.351.1.0" />
<dxl:ArrayType Mdid="0.1007.1.0" />
<dxl:MinAgg Mdid="0.2132.1.0" />
<dxl:MaxAgg Mdid="0.2116.1.0" />
<dxl:AvgAgg Mdid="0.2101.1.0" />
<dxl:SumAgg Mdid="0.2108.1.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.25.1.0" Name="text" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="true" IsFixedLength="false" Length="-1" PassByValue="false">
<dxl:EqualityOp Mdid="0.98.1.0" />
<dxl:InequalityOp Mdid="0.531.1.0" />
<dxl:LessThanOp Mdid="0.664.1.0" />
<dxl:LessThanEqualsOp Mdid="0.665.1.0" />
<dxl:GreaterThanOp Mdid="0.666.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.667.1.0" />
<dxl:ComparisonOp Mdid="0.360.1.0" />
<dxl:ArrayType Mdid="0.1009.1.0" />
<dxl:MinAgg Mdid="0.2145.1.0" />
<dxl:MaxAgg Mdid="0.2129.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.26.1.0" Name="oid" IsRedistributable="true" IsHashable="true" IsMergeJoinable="true" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.607.1.0" />
<dxl:InequalityOp Mdid="0.608.1.0" />
<dxl:LessThanOp Mdid="0.609.1.0" />
<dxl:LessThanEqualsOp Mdid="0.611.1.0" />
<dxl:GreaterThanOp Mdid="0.610.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.612.1.0" />
<dxl:ComparisonOp Mdid="0.356.1.0" />
<dxl:ArrayType Mdid="0.1028.1.0" />
<dxl:MinAgg Mdid="0.2118.1.0" />
<dxl:MaxAgg Mdid="0.2134.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.27.1.0" Name="tid" IsRedistributable="true" IsHashable="false" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="6" PassByValue="false">
<dxl:EqualityOp Mdid="0.387.1.0" />
<dxl:InequalityOp Mdid="0.402.1.0" />
<dxl:LessThanOp Mdid="0.2799.1.0" />
<dxl:LessThanEqualsOp Mdid="0.2801.1.0" />
<dxl:GreaterThanOp Mdid="0.2800.1.0" />
<dxl:GreaterThanEqualsOp Mdid="0.2802.1.0" />
<dxl:ComparisonOp Mdid="0.2794.1.0" />
<dxl:ArrayType Mdid="0.1010.1.0" />
<dxl:MinAgg Mdid="0.2798.1.0" />
<dxl:MaxAgg Mdid="0.2797.1.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.29.1.0" Name="cid" IsRedistributable="false" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.385.1.0" />
<dxl:InequalityOp Mdid="0.0.0.0" />
<dxl:LessThanOp Mdid="0.0.0.0" />
<dxl:LessThanEqualsOp Mdid="0.0.0.0" />
<dxl:GreaterThanOp Mdid="0.0.0.0" />
<dxl:GreaterThanEqualsOp Mdid="0.0.0.0" />
<dxl:ComparisonOp Mdid="0.0.0.0" />
<dxl:ArrayType Mdid="0.1012.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:Type Mdid="0.28.1.0" Name="xid" IsRedistributable="false" IsHashable="true" IsMergeJoinable="false" IsComposite="false" IsTextRelated="false" IsFixedLength="true" Length="4" PassByValue="true">
<dxl:EqualityOp Mdid="0.352.1.0" />
<dxl:InequalityOp Mdid="0.0.0.0" />
<dxl:LessThanOp Mdid="0.0.0.0" />
<dxl:LessThanEqualsOp Mdid="0.0.0.0" />
<dxl:GreaterThanOp Mdid="0.0.0.0" />
<dxl:GreaterThanEqualsOp Mdid="0.0.0.0" />
<dxl:ComparisonOp Mdid="0.0.0.0" />
<dxl:ArrayType Mdid="0.1011.1.0" />
<dxl:MinAgg Mdid="0.0.0.0" />
<dxl:MaxAgg Mdid="0.0.0.0" />
<dxl:AvgAgg Mdid="0.0.0.0" />
<dxl:SumAgg Mdid="0.0.0.0" />
<dxl:CountAgg Mdid="0.2147.1.0" />
</dxl:Type>
<dxl:MDCast Mdid="3.25.1.0;25.1.0" Name="text" BinaryCoercible="true" SourceTypeId="0.25.1.0" DestinationTypeId="0.25.1.0" CastFuncId="0.0.0.0" CoercePathType="0" />
<dxl:MDCast Mdid="3.1043.1.0;25.1.0" Name="text" BinaryCoercible="true" SourceTypeId="0.1043.1.0" DestinationTypeId="0.25.1.0" CastFuncId="0.0.0.0" CoercePathType="0" />
<dxl:RelationStatistics Mdid="2.4015133.1.1" Name="foo" Rows="0.000000" EmptyRelation="true" />
<dxl:Relation Mdid="0.4015133.1.1" Name="foo" IsTemporary="false" HasOids="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="7,1" NumberLeafPartitions="0">
<dxl:Columns>
<dxl:Column Name="a" Attno="1" Mdid="0.1043.1.0" Nullable="true" ColWidth="16">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="ctid" Attno="-1" Mdid="0.27.1.0" Nullable="false" ColWidth="6">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmin" Attno="-3" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmin" Attno="-4" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmax" Attno="-5" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmax" Attno="-6" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="tableoid" Attno="-7" Mdid="0.26.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="gp_segment_id" Attno="-8" Mdid="0.23.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
</dxl:Columns>
<dxl:IndexInfoList />
<dxl:Triggers />
<dxl:CheckConstraints />
</dxl:Relation>
<dxl:ColumnStatistics Mdid="1.4015133.1.1.0" Name="a" Width="8.000000" NullFreq="0.000000" NdvRemain="0.000000" FreqRemain="0.000000" ColStatsMissing="false" />
<dxl:GPDBScalarOp Mdid="0.98.1.0" Name="=" ComparisonType="Eq" ReturnsNullOnNullInput="false" IsNDVPreserving="false">
<dxl:LeftType Mdid="0.25.1.0" />
<dxl:RightType Mdid="0.25.1.0" />
<dxl:ResultType Mdid="0.16.1.0" />
<dxl:OpFunc Mdid="0.67.1.0" />
<dxl:Commutator Mdid="0.98.1.0" />
<dxl:InverseOp Mdid="0.531.1.0" />
</dxl:GPDBScalarOp>
<dxl:RelationStatistics Mdid="2.4015159.1.1" Name="bar" Rows="0.000000" EmptyRelation="true" />
<dxl:Relation Mdid="0.4015159.1.1" Name="bar" IsTemporary="false" HasOids="false" StorageType="Heap" DistributionPolicy="Hash" DistributionColumns="0" Keys="7,1" NumberLeafPartitions="0">
<dxl:Columns>
<dxl:Column Name="b" Attno="1" Mdid="0.1043.1.0" Nullable="true" ColWidth="16">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="ctid" Attno="-1" Mdid="0.27.1.0" Nullable="false" ColWidth="6">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmin" Attno="-3" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmin" Attno="-4" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="xmax" Attno="-5" Mdid="0.28.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="cmax" Attno="-6" Mdid="0.29.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="tableoid" Attno="-7" Mdid="0.26.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
<dxl:Column Name="gp_segment_id" Attno="-8" Mdid="0.23.1.0" Nullable="false" ColWidth="4">
<dxl:DefaultValue />
</dxl:Column>
</dxl:Columns>
<dxl:IndexInfoList />
<dxl:Triggers />
<dxl:CheckConstraints />
</dxl:Relation>
</dxl:Metadata>
<dxl:Query>
<dxl:OutputColumns>
<dxl:Ident ColId="1" ColName="a" TypeMdid="0.1043.1.0" />
<dxl:Ident ColId="9" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:OutputColumns>
<dxl:CTEList />
<dxl:LogicalJoin JoinType="Inner">
<dxl:LogicalGet>
<dxl:TableDescriptor Mdid="0.4015133.1.1" TableName="foo">
<dxl:Columns>
<dxl:Column ColId="1" Attno="1" ColName="a" TypeMdid="0.1043.1.0" ColWidth="16" />
<dxl:Column ColId="2" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" />
<dxl:Column ColId="3" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" />
<dxl:Column ColId="4" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" />
<dxl:Column ColId="5" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" />
<dxl:Column ColId="6" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" />
<dxl:Column ColId="7" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" />
<dxl:Column ColId="8" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" />
</dxl:Columns>
</dxl:TableDescriptor>
</dxl:LogicalGet>
<dxl:LogicalGet>
<dxl:TableDescriptor Mdid="0.4015159.1.1" TableName="bar">
<dxl:Columns>
<dxl:Column ColId="9" Attno="1" ColName="b" TypeMdid="0.1043.1.0" ColWidth="16" />
<dxl:Column ColId="10" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" />
<dxl:Column ColId="11" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" />
<dxl:Column ColId="12" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" />
<dxl:Column ColId="13" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" />
<dxl:Column ColId="14" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" />
<dxl:Column ColId="15" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" />
<dxl:Column ColId="16" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" />
</dxl:Columns>
</dxl:TableDescriptor>
</dxl:LogicalGet>
<dxl:Comparison ComparisonOperator="=" OperatorMdid="0.98.1.0">
<dxl:Cast TypeMdid="0.25.1.0" FuncId="0.0.0.0">
<dxl:Ident ColId="1" ColName="a" TypeMdid="0.1043.1.0" />
</dxl:Cast>
<dxl:Cast TypeMdid="0.25.1.0" FuncId="0.0.0.0">
<dxl:Ident ColId="9" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:Cast>
</dxl:Comparison>
</dxl:LogicalJoin>
</dxl:Query>
Plan
<dxl:Plan Id="0" SpaceSize="0">
<dxl:GatherMotion InputSegments="0,1" OutputSegments="-1">
<dxl:Properties>
<dxl:Cost StartupCost="0" TotalCost="2.117188" Rows="1.000000" Width="16" />
</dxl:Properties>
<dxl:ProjList>
<dxl:ProjElem ColId="0" Alias="a">
<dxl:Ident ColId="0" ColName="a" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
<dxl:ProjElem ColId="8" Alias="b">
<dxl:Ident ColId="8" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
</dxl:ProjList>
<dxl:Filter />
<dxl:SortingColumnList />
<dxl:HashJoin JoinType="Inner">
<dxl:Properties>
<dxl:Cost StartupCost="0" TotalCost="1.109375" Rows="1.000000" Width="16" />
</dxl:Properties>
<dxl:ProjList>
<dxl:ProjElem ColId="0" Alias="a">
<dxl:Ident ColId="0" ColName="a" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
<dxl:ProjElem ColId="8" Alias="b">
<dxl:Ident ColId="8" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
</dxl:ProjList>
<dxl:Filter />
<dxl:JoinFilter />
<dxl:HashCondList>
<dxl:Comparison ComparisonOperator="=" OperatorMdid="0.98.1.0">
<dxl:Cast TypeMdid="0.25.1.0" FuncId="0.0.0.0">
<dxl:Ident ColId="0" ColName="a" TypeMdid="0.1043.1.0" />
</dxl:Cast>
<dxl:Cast TypeMdid="0.25.1.0" FuncId="0.0.0.0">
<dxl:Ident ColId="8" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:Cast>
</dxl:Comparison>
</dxl:HashCondList>
<dxl:TableScan>
<dxl:Properties>
<dxl:Cost StartupCost="0" TotalCost="0.007812" Rows="1.000000" Width="8" />
</dxl:Properties>
<dxl:ProjList>
<dxl:ProjElem ColId="0" Alias="a">
<dxl:Ident ColId="0" ColName="a" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
</dxl:ProjList>
<dxl:Filter />
<dxl:TableDescriptor Mdid="0.4015133.1.1" TableName="foo">
<dxl:Columns>
<dxl:Column ColId="0" Attno="1" ColName="a" TypeMdid="0.1043.1.0" ColWidth="16" />
<dxl:Column ColId="1" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" />
<dxl:Column ColId="2" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" />
<dxl:Column ColId="3" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" />
<dxl:Column ColId="4" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" />
<dxl:Column ColId="5" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" />
<dxl:Column ColId="6" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" />
<dxl:Column ColId="7" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" />
</dxl:Columns>
</dxl:TableDescriptor>
</dxl:TableScan>
<dxl:TableScan>
<dxl:Properties>
<dxl:Cost StartupCost="0" TotalCost="0.007812" Rows="1.000000" Width="8" />
</dxl:Properties>
<dxl:ProjList>
<dxl:ProjElem ColId="8" Alias="b">
<dxl:Ident ColId="8" ColName="b" TypeMdid="0.1043.1.0" />
</dxl:ProjElem>
</dxl:ProjList>
<dxl:Filter />
<dxl:TableDescriptor Mdid="0.4015159.1.1" TableName="bar">
<dxl:Columns>
<dxl:Column ColId="8" Attno="1" ColName="b" TypeMdid="0.1043.1.0" ColWidth="16" />
<dxl:Column ColId="9" Attno="-1" ColName="ctid" TypeMdid="0.27.1.0" />
<dxl:Column ColId="10" Attno="-3" ColName="xmin" TypeMdid="0.28.1.0" />
<dxl:Column ColId="11" Attno="-4" ColName="cmin" TypeMdid="0.29.1.0" />
<dxl:Column ColId="12" Attno="-5" ColName="xmax" TypeMdid="0.28.1.0" />
<dxl:Column ColId="13" Attno="-6" ColName="cmax" TypeMdid="0.29.1.0" />
<dxl:Column ColId="14" Attno="-7" ColName="tableoid" TypeMdid="0.26.1.0" />
<dxl:Column ColId="15" Attno="-8" ColName="gp_segment_id" TypeMdid="0.23.1.0" />
</dxl:Columns>
</dxl:TableDescriptor>
</dxl:TableScan>
</dxl:HashJoin>
</dxl:GatherMotion>
</dxl:Plan>