Greenplum查询优化揭秘

2020-07-08 18:08:49 浏览数 (1)

Greenplum查询优化揭秘

目录

Greenplum查询优化揭秘 1

目录 1

1 Greenplum查询优化器和查询计划介绍 1

1.1 Greenplum查询优化器介绍 1

1.2 Greenplum查询计划介绍 1

1.3 计划节点的类型 2

2 Greenplum查询优化器的的具体处理过程 2

2.1 查询树的预处理 2

2.1.1 查询树的预处理(早期) 3

2.1.2 查询树的预处理(后期) 7

2.2 扫描/链接优化 10

2.3 动态规划 10

2.4 扫描/连接之外的优化 10

2.5 计划树的后处理 11

1 Greenplum查询优化器和查询计划介绍

1.1 Greenplum查询优化器介绍

对于给定的查询语句,找到”代价”最小的查询计划的顺序

1、对于同一个查询语句,一般可以由多种方式执行

2、查询优化器尽可能去遍历每一种可能的执行方式

3、找到”代价”最小的执行方式,并把它转化为可执行的计划树

1.2 Greenplum查询计划介绍

1、一个查询计划就是一个由计划节点组成的树

2、每个计划节点代表了一个特定类型的处理操作,计划节点中包含了执行器执行所需要的全部信息

3、在执行时,计划节点产生输出元组

4、一般来说,扫描节点从数据表中获取输入元组

5、大部分其他节点层他们的子计划节点中获取输入元组,并产生输出元祖

1.3 计划节点的类型

1、扫描节点

顺序扫描,索引扫描,位图扫描

2、链接节点

Nestloop,hash,merge

3、非SPJ节点

Sort,aggregate,set operations(UNION etc)

扫描节点实例

2 Greenplum查询优化器的的具体处理过程

2.1 查询树的预处理

尽可能的简化查询树,收集有用的信息

2.1.1 查询树的预处理(早期)

2.1.1.1 简化常量表达式

1、简化函数表达式

函数本身是”严格”的,并且输入包含NULL值,示例如下

Int4eq(1,NULL) => NULL

函数本身是”IMMUTABLE”的,并且输入参数全都常量

2 2 => 4

2、简化常量表达式

简化布尔表达式

“x or true” => “true”

“ x AND false ” => “false”

3、简化CASE表达式

CASE WHEN 2 2 = 4 THEN x 1

ELSE 1/0 END

= > x 1

... not “ERROR:division by zero”

4、为什么简化常量表达式

A、仅需要做一次计算,而不是为每行元组都做一次计算

B、视图展开和函数内连都可能会带来新的常量表达式简化的机会

C、简化常量表达式也为统计信息类的函数减少了计算量

2.1.1.2内连简单的SQL函数

create function incr4(int) returns int as ‘select $1 ( 2 2 ) ’ LANGUAGE SQL;

select incr4(a) from foo;

== >

Select a 4 from foo;

为什么使用内联简单的SQL函数

1、避免SQL函数调用的代价

2、为简化常量表达式提供新的机会

2.1.1.3 提升IN,EXISTS类型的子链接

子链接是指吃现在表达式中的子查询,通常出现在where或join/on子句中

select * from foo where exists (select 1 from bar where foo.a = bar.c);

== >

Select * from foo *SEMI JOIN* bar on foo.a = bar.c

查询树的内部结构图

优化后的内部结构图

2.1.1.4 提升子查询

子查询一般以范围表的方式存在,通常出现在from字句中

select * from foo join (select bar.c from bar join baz on true) as sub on foo.a = sub.c;

==>

select * from foo join (bar join baz on true) on foo.a = bar.c;

提升之前的查询计划图

提升之后的子查询计划图

为什么提升子查询

1、通过把子查询提升到父查询之中,就可以使子查询参与整个计划搜索空间,从而找到更好的执行计划。

2、否则,我们不得不为了子查询单独做计划树,然后在为父查询做计划时把子查询当做是一个”黑盒子”

2.1.1.5消除外链接

消除外链接的实例

外链接的上层有”严格”的约束条件,且该条件限定了来自nullable side的某一变量为非null值,则外链接可以转化成内连接

select ... from foo left join bar on (...) where bar.d = 42;

==>

select ... from foo inner join bar on (...) where bar.d = 42;

2.1.2 查询树的预处理(后期)

2.1.2.1 分发where和join/on约束条件

1、一般来说,我们期望可以尽可能的下推约束条件

2、如果只有内连接,我们可以把一个约束条件下推到它的”自然语义”位置

3、如果存在外链接,那么约束条件的下推可能会受到阻碍,从而无法下载到它的“自然语义”的位置

4、对于被外连接阻碍的约束条件,我们通过让他们的“required_relids”包含进外链接锁需要的所有基表,从而避免该约束条件被下推到外链接之下

被外链接阻碍的约束条件案例

2.1.2.2 收集关于链接顺序限制的信息

1、外链接会在一定程度上限制连接顺序的交换

2、非FULL-JOIN可以和一个外链接的左端(LHS)自由结合

3、通常非FULL-JOIN不可以和外链接的有段(RHS)结合

2.1.2.3 消除无用链接

1、必须是做链接,且内表是基表

2、内表的列没有在该连接之上上使用

3、连接条件最多只可能匹配内表中的一个元组

消除无用链接实例

2.2 扫描/链接优化

为查询语句中扫描和链接部分做计划,实例如下:

1、首先为基表确定扫描路径,估计扫描路径的代价和大小

2、利用动态规划算法,搜索整个链接顺序空间,生成链接路径

3、在搜索链接顺序空间是,需要考虑到由外链接带来的链接顺序的限制

2.3 动态规划

1、为每一个基表生成扫描路径

2、为所有可能的两个表的链接生成链接路径

3、为所有可能的三个表的链接生成链接路径

4、为所有可能的四个表的链接生成链接路径

*****

5、直到所有基表都连接在了一起

2.4 扫描/连接之外的优化

为查询语句中扫描和链接之外的部分做计划,扫描/连接之外的优化的步骤如下:

1、首先为表确定扫描路径,估计扫描路径的代价和大小

2、利用动态规划算法,搜索整个链接顺序空间,生成链接路径

3、在搜索链接顺序空间时,需要考虑到由外链接带来的链接顺序的限制

4、处理GROUP BY ,aggregation,windom,functions,DISTINCT

5、处理集合操作,UNION/INTERSECT/EXCEPT

6、如果ORDER BY需要,添加最后的SORT节点

7、添加LockRows,Limit,ModifyTable节点

1、主要处理查询语句中FROM和WHERE部分

2、同时也会考虑到ORDER BY信息

3、有代价来驱动

2.5 计划树的后处理

把优化结果转化成执行器可以执行的形式

1、把代价最小的路径转化成计划树

2、调整计划树中的一些细节,包含以下步骤

1)、展平子查询的范围表

2)把上层计划节点中的变量变成OUTER_VAR或时INNER_VAR的形式,来指向自己花的输出

3)删除不必要的SubqueryScan,Append等节点

0 人点赞