多表关联的逻辑默认是在DN节点执行,在发生重分布后,可能会因为重分布原因性能明显下降。
针对此问题,TeleDB支持通过参数prefer_olap设置,可以选择将关联逻辑上拉到CN节点执行,避免DN之间的重分布。参数prefer_olap默认为on,表示关联下推到DN执行,off则表示关联上拉到DN执行。
这里需要注意,设置关联上拉CN节点执行,需要提前做好评估,如果上拉数据量过大,大量并发SQL发起上拉数据到CN动作,会导致CN节点负载过高,甚至OOM。
通常可以在TP类业务中可以针对SQL会话级设置上拉,性能会有所提升,同时CN节点应配置较大的资源,避免OOM发生。
例如,下面的SQL,teledb_1关联没有用到分布键,发生了重分布。
teledb=# explain select teledb_1.* from teledb_1,teledb_2 where teledb_1.f1=teledb_2.f1 ;
QUERY PLAN
------------------------------------------------------------------------------------------------
Remote Subquery Scan on all (dn001,dn002) (cost=29.80..186.32 rows=3872 width=40)
-> Hash Join (cost=29.80..186.32 rows=3872 width=40)
Hash Cond: (teledb_1.f1 = teledb_2.f1)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..158.40 rows=880 width=40)
Distribute results by S: f1
-> Seq Scan on teledb_1 (cost=0.00..18.80 rows=880 width=40)
-> Hash (cost=18.80..18.80 rows=880 width=4)
-> Seq Scan on teledb_2 (cost=0.00..18.80 rows=880 width=4)
(8 rows)
设置prefer_olap=off后,关联上拉到CN上执行,重分布消失。
执行计划如下:
teledb=# set prefer_olap to off;
SET
teledb=# explain select teledb_1.* from teledb_1,teledb_2 where teledb_1.f1=teledb_2.f1 ;
QUERY PLAN
-----------------------------------------------------------------------------------------------
Hash Join (cost=29.80..186.32 rows=3872 width=40)
Hash Cond: (teledb_1.f1 = teledb_2.f1)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..158.40 rows=880 width=40)
-> Seq Scan on teledb_1 (cost=0.00..18.80 rows=880 width=40)
-> Hash (cost=126.72..126.72 rows=880 width=4)
-> Remote Subquery Scan on all (dn001,dn002) (cost=100.00..126.72 rows=880 width=4)
-> Seq Scan on teledb_2 (cost=0.00..18.80 rows=880 width=4)
(7 rows)