现象描述
在做场景性能测试时,发现某场景大部分时间是CN端在做window agg,占到总执行时间95%以上,系统资源不能充分利用。研究发现该场景的特点是:将两列分别求sum作为一个子查询,外层对两列的和再求和后做trunc,然后排序。
表结构如下所示:
with(orientation=column)DISTRIBUTEBYhash(imsi);
查询语句如下所示:
SELECTCOUNT(1)over()ASDATACNT,
IMSIASIMSI_IMSI,
CAST(TRUNC(((SUM(L4_UL_THROUGHPUT)+SUM(L4_DW_THROUGHPUT))),0)AS
DECIMAL(20))ASTOTAL_VOLOME_KPIID
FROMpublic.testAStest
GROUPBYIMSI
orderbyTOTAL_VOLOME_KPIIDDESC;
执行计划如下:
->VectorSort(cost=10.68..10.70rows=10width=12)
SortKey:((trunc((((sum(l4_ul_throughput))+(sum(l4_dw_throughput))))::numeric,0))::numeric(20,0))
->VectorWindowAgg(cost=10.09..10.51rows=10width=12)
->VectorStreaming(type:GATHER)(cost=242.04..246.84rows=240width=12)
Node/s:Alldatanodes
->VectorHashAggregate(cost=10.09..10.29rows=10width=12)
GroupByKey:imsi
->CStoreScanontest(cost=0.00..10.01rows=10width=12)
可以看到window agg和sort全部在CN端执行,耗时非常严重。
优化分析
尝试将语句改写为子查询。
FROM(SELECTIMSIASIMSI_IMSI,
CAST(TRUNC(((SUM(L4_UL_THROUGHPUT)+SUM(L4_DW_THROUGHPUT))),
0)ASDECIMAL(20))ASTOTAL_VOLOME_KPIID
FROMpublic.testAStest
GROUPBYIMSI
ORDERBYTOTAL_VOLOME_KPIIDDESC);
将trunc两列的和作为一个子查询,然后在子查询的外面做window agg,这样排序就可以下推了,执行计划如下:
->VectorWindowAgg(cost=10.45..10.70rows=10width=24)
->VectorStreaming(type:GATHER)(cost=250.83..253.83rows=240width=24)
Node/s:Alldatanodes
->VectorSort(cost=10.45..10.48rows=10width=12)
SortKey:((trunc(((sum(test.l4_ul_throughput)+sum(test.l4_dw_throughput)))::numeric,0))::numeric(20,0))
->VectorHashAggregate(cost=10.09..10.29rows=10width=12)
GroupByKey:test.imsi
->CStoreScanontest(cost=0.00..10.01rows=10width=12)
经过SQL改写,性能由120s提升到7s,优化效果明显。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




