作者小头像 Lv.1
20 成长值

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

人工智能、大数据、数据库、云计算
个人勋章
TA还没获得勋章~
成长雷达
20
0
0
0
0

个人资料

个人介绍

这个人很懒,什么都没有留下

感兴趣或擅长的领域

人工智能、大数据、数据库、云计算

达成规则

发布时间 2021/05/08 18:10:24 最后回复 瘸子那条好腿 2021/05/18 15:47:35 版块 数仓GaussDB(DWS)
5064 8 0
他的回复:
GaussDB(DWS)目前不支持离散型的分区划分策略,即所有分区的边界必须是依次首位链接的,对于楼主的需求,可以直接按天划分区间,然后允许一些分区里面没有数据,例如:postgres=# create table t1 (id int, t_time timestamp) partition by range(t_time) (partition "2021" start('2021-04-29') end('2021-05-10') every('1 day')); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE postgres=# select p.relname, p.parttype, p.parentid, p.reltuples, p.boundaries from pg_partition p, pg_class c where c.oid = p.parentid and c.relname = 't1'; relname | parttype | parentid | reltuples | boundaries ---------+----------+----------+-----------+------------------------- t1 | r | 44843 | 0 | 2021_0 | p | 44843 | 0 | {"2021-04-29 00:00:00"} 2021_1 | p | 44843 | 0 | {"2021-04-30 00:00:00"} 2021_2 | p | 44843 | 0 | {"2021-05-01 00:00:00"} 2021_3 | p | 44843 | 0 | {"2021-05-02 00:00:00"} 2021_4 | p | 44843 | 0 | {"2021-05-03 00:00:00"} 2021_5 | p | 44843 | 0 | {"2021-05-04 00:00:00"} 2021_6 | p | 44843 | 0 | {"2021-05-05 00:00:00"} 2021_7 | p | 44843 | 0 | {"2021-05-06 00:00:00"} 2021_8 | p | 44843 | 0 | {"2021-05-07 00:00:00"} 2021_9 | p | 44843 | 0 | {"2021-05-08 00:00:00"} 2021_10 | p | 44843 | 0 | {"2021-05-09 00:00:00"} 2021_11 | p | 44843 | 0 | {"2021-05-10 00:00:00"} (13 rows)
他的回复:
对于楼主的第一个疑问:首先我们弄清楚每种计划的代表的意义。(1)第一种,下推语句计划:  这种计划是指CN将语句发送给DN执行,并收取执行结果,例如:select l_shipdate from lineitem where l_orderkey  10;  这条语句可以直接发给各DN各自执行,然后CN依次收结果即可,一般仅有一个Data Node Scan算子,看执行计划:explain select l_shipdate from lineitem where l_orderkey  10;                     QUERY PLAN --------------------------------------------------  Data Node Scan  (cost=0.00..0.00 rows=0 width=0)    Node/s: All datanodes (2 rows) 这个计划就表示,CN把语句发给DN,每个DN上进行Scan,这种计划可以通过设置guc参数enable_fast_query_shipping=off来关闭:postgres=# set enable_fast_query_shipping=off; SET postgres=# explain select l_shipdate from lineitem where l_orderkey  10;  id |               operation                | E-rows | E-memory | E-width | E-costs ----+----------------------------------------+--------+----------+---------+---------   1 | ->  Row Adapter                        |     18 |          |       8 | 61.56   2 |    ->  Vector Streaming (type: GATHER) |     18 |          |       8 | 61.56   3 |       ->  CStore Scan on lineitem      |     18 | 1MB      |       8 | 51.56 (3 rows)  Predicate Information (identified by plan id) -----------------------------------------------    3 --CStore Scan on lineitem          Filter: (l_orderkey  10) (2 rows)    ====== Query Summary ===== ---------------------------------  System available mem: 9279897KB  Query Max mem: 9473228KB  Query estimated mem: 1024KB (3 rows)(2)第二种,分布式执行计划:原理:CN根据语句生成执行计划,并下发计划给DN进行执行,各个DN执行过程中存在数据交互(有Stream节点),例如:postgres=# explain select count(*) from lineitem where l_orderkey  10;  id |                 operation                 | E-rows | E-memory | E-width | E-costs ----+-------------------------------------------+--------+----------+---------+---------   1 | ->  Row Adapter                           |      1 |          |       8 | 61.60   2 |    ->  Vector Aggregate                   |      1 |          |       8 | 61.60   3 |       ->  Vector Streaming (type: GATHER) |      4 |          |       8 | 61.60   4 |          ->  Vector Aggregate             |      4 | 1MB      |       8 | 51.60   5 |             ->  CStore Scan on lineitem   |     18 | 1MB      |       0 | 51.56 (5 rows)  Predicate Information (identified by plan id) -----------------------------------------------    5 --CStore Scan on lineitem          Filter: (l_orderkey  10) (2 rows)    ====== Query Summary ===== ---------------------------------  System available mem: 9279897KB  Query Max mem: 9473228KB  Query estimated mem: 2048KB (3 rows)这个计划中,l_orderkey10已经作为Filter下推到DN上了,聚集操作(count)则是分两步,第一步在各个DN上各自做count,然后CN将DN的结果(count数)收集上来,再做一次count,所以计划中就有两个Vector Aggregate,中间有个Stream节点(GATHER)用于收取各个DN结果集。这种分布式计划的意义就是把执行计划中的各个算子分解到各个DN上去做,中间需要交互数据就添加Stream节点,最后在CN上汇报最终执行结果。分布式执行计划可以通过设置guc参数enable_stream_operator=off来关闭,如果把stream节点关闭,就等于DN之间不能进行数据交互了,很多算子(如Aggregate,Hash Join)就无法分布式执行了,就会退化为第三种计划,生成发送语句的分布式计划。(3)第三种计划,生成发送语句的分布式计划:原理:CN生成计划后,下推部分查询(多为基表扫描语句和简单的聚集操作等)到DN进行执行,获取中间结果到CN,然后在CN执行剩下的部分,例如上面的分布式计划,如果把enable_stream_operator关了,则计划为:postgres=# set enable_stream_operator=off; SET postgres=# explain verbose select count(*) from lineitem where l_orderkey  10;                                       QUERY PLAN ---------------------------------------------------------------------------------------  Aggregate  (cost=0.04..0.06 rows=1 width=8)    Output: pg_catalog.count(*)    ->  Data Node Scan on "__REMOTE_GROUP_QUERY__"  (cost=0.00..0.00 rows=18 width=0)          Output: (count(*))          Node/s: All datanodes          Remote query: SELECT count(*) FROM ONLY public.lineitem WHERE l_orderkey  10 (6 rows)这个就表示,原语句大部分操作作为语句(一个Filter和一个count)下推到各个DN执行,最后各个DN的count结果在CN上在执行一次,注意没有Stream节点,收据收集是Data Node Scan算子。这种计划说的通俗一点就是,把能下推的部分下推,剩余不能下推的都在CN上做,再如下面的语句:postgres=# explain verbose select count(*) from lineitem l1, lineitem l2 where l1.l_orderkey = l2.l_orderkey + 1;                                                 QUERY PLAN ----------------------------------------------------------------------------------------------------------  Aggregate  (cost=108.78..108.79 rows=1 width=8)    Output: count(*)    ->  Hash Join  (cost=37.51..97.53 rows=4501 width=0)          Hash Cond: (l1.l_orderkey = (l2.l_orderkey + 1))          ->  Data Node Scan on lineitem "_REMOTE_TABLE_QUERY_"  (cost=0.00..0.00 rows=3001 width=4)                Output: l1.l_orderkey                Node/s: All datanodes                Remote query: SELECT l_orderkey FROM ONLY public.lineitem l1 WHERE true          ->  Hash  (cost=0.00..0.00 rows=3001 width=4)                Output: l2.l_orderkey                ->  Data Node Scan on lineitem "_REMOTE_TABLE_QUERY_"  (cost=0.00..0.00 rows=3001 width=4)                      Output: l2.l_orderkey                      Node/s: All datanodes                      Remote query: SELECT l_orderkey FROM ONLY public.lineitem l2 WHERE true (14 rows)这个计划中的Hash Join就是在CN上做的,需要的数据通过Data Node Scan节点来获取,基本扫描下推到DN上了,表链接在CN上执行。小结一下:计划种类适用场景示例guc参数计划特点下推语句计划语句整体可下推,DN之间无需数据交互,CN汇总数据select l_shipdate from lineitem where l_orderkey 10;enable_fast_query_shipping=on 代表开启Data Node Scan算子分布式计划计划下推,各DN之间可能有数据交互select count(*) from lineitem where l_orderkey 10;enable_stream_operator=on 代表开启Stream算子发送语句的分布式计划不满足上述两种情况的场景,可下推部分下推,其余在CN上执行,一般性能较差select count(l_orderkey order by l_orderkey) from lineitem where l_orderkey 10;-Data Node Scan算子Note:当无法生成第一种和第二种计划时,第三种计划是最后一条路了,就是把数据都拿到CN上,只要有足够时间,总是可以执行出来的。对于第二个疑问:我们看个语句:select count(l_orderkey order by l_orderkey) from lineitem where l_orderkey  10;这个语句的执行计划如下(enable_fast_query_shipping=on,enable_stream_operator=on)postgres=# explain (verbose on, costs off) select count(l_orderkey order by l_orderkey) from lineitem where l_orderkey  10;                                        QUERY PLAN -----------------------------------------------------------------------------------------  Aggregate    Output: count(lineitem.l_orderkey ORDER BY lineitem.l_orderkey)    ->  Data Node Scan on lineitem "_REMOTE_TABLE_QUERY_"          Output: lineitem.l_orderkey          Node/s: All datanodes          Remote query: SELECT l_orderkey FROM ONLY public.lineitem WHERE l_orderkey  10 (6 rows)这个计划走的就是第三种计划了,依据是:有Data Node Scan算子,CN需要做Aggregate,为何不能生成第一种或第二种计划呢?看输出列:count(l_orderkey order by l_orderkey),这个是要对l_orderkey进行排序后在count,既然是要全局排序,那么这个order by只能在CN上做了,因此第一种计划排除,count也不能在DN上做,那就是说所有算子(order by和count)都只能在CN上做,只有l_orderkey10可以下推到DN做,也无法生成分布式计划。最后只能用最笨的办法,生成第三种执行计划了。其实从语义上讲,这里的count内部的order by语句没有意义,加与不加结果都一样,加了之后会导致无法生成分布式计划,从而影响性能。总结来说,我们有一些不支持下推的语句类型,上面这个例子就是其中之一,其他的还有:不支持returning语句下推count(distinct expr)中的字段不支持重分布,则不支持下推不支持distinct on用法下推Fulljoin的join列如果不支持重分布,则不支持下推不支持数组表达式下推With Recursive当前版本不支持下推等等,详细介绍请看手册 https://support.huaweicloud.com/devg-dws/dws_04_0107.html希望对你有所帮助!
发布时间 2020/06/19 20:49:14 最后回复 Ivan_2020 2020/06/20 15:45:04 版块 数仓GaussDB(DWS)
1434 5 1