GaussDB(DWS)性能调优:Sort+Groupagg聚集引起的性能瓶颈案例
本文分享自华为云社区《GaussDB(DWS)性能调优:Sort+Groupagg聚集引起的性能瓶颈案例》,作者: O泡果奶~ 。
本文针对SQL语句长时间执行不出来,且verbose执行计划中出现Sort+GroupAgg聚集方式的案例进行分析。
1、【问题描述】
语句执行时间过长,2300s+也无法得出结果。从verbose执行计划可以看出存在sort聚合。
2、【原始语句】
SELECT /*+ set global(agg_redistribute_enhancement on) set global (best_agg_plan 3)*/ dm_ebg_glb_kpi_sum_w_v."na_level_name", dm_ebg_glb_kpi_sum_w_v."na_level", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_code", dm_ebg_glb_kpi_sum_w_v."period_id", dm_ebg_glb_kpi_sum_w_v."year", dm_ebg_glb_kpi_sum_w_v."month", dm_ebg_glb_kpi_sum_w_v."report_category_cn_name", dm_ebg_glb_kpi_sum_w_v."report_category_en_name", dm_ebg_glb_kpi_sum_w_v."currency_code", dm_ebg_glb_kpi_sum_w_v."exchange_rate_type_cn_name", dm_ebg_glb_kpi_sum_w_v."exchange_rate_type_en_name", dm_ebg_glb_kpi_sum_w_v."report_item_code", dm_ebg_glb_kpi_sum_w_v."report_item_cn_name", dm_ebg_glb_kpi_sum_w_v."report_item_en_name", dm_ebg_glb_kpi_sum_w_v."report_item_type", dm_ebg_glb_kpi_sum_w_v."report_item_flag", dm_ebg_glb_kpi_sum_w_v."region_code", dm_ebg_glb_kpi_sum_w_v."region_cn_name", dm_ebg_glb_kpi_sum_w_v."region_en_name", dm_ebg_glb_kpi_sum_w_v."oversea_flag", dm_ebg_glb_kpi_sum_w_v."repoffice_code", dm_ebg_glb_kpi_sum_w_v."repoffice_cn_name", dm_ebg_glb_kpi_sum_w_v."repoffice_en_name", dm_ebg_glb_kpi_sum_w_v."ebg_focus_cn_name", dm_ebg_glb_kpi_sum_w_v."ebg_focus_en_name", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."named_account_flag", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_code", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_cn_name", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_en_name", dm_ebg_glb_kpi_sum_w_v."industry_class_code", dm_ebg_glb_kpi_sum_w_v."industry_class_cn_name", dm_ebg_glb_kpi_sum_w_v."industry_class_en_name", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_code", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_cn_name", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_en_name", dm_ebg_glb_kpi_sum_w_v."focus_industry_cn_name", dm_ebg_glb_kpi_sum_w_v."focus_industry_en_name", dm_ebg_glb_kpi_sum_w_v."sales_mode_code", dm_ebg_glb_kpi_sum_w_v."sales_mode_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_mode_en_name", SUM(dm_ebg_glb_kpi_sum_w_v."ptd_amt") as "ptd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."py_ptd_amt") as "py_ptd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."pp_ptd_amt") as "pp_ptd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."qtd_amt") as "qtd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."py_qtd_amt") as "py_qtd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."pp_qtd_amt") as "pp_qtd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."ytd_amt") as "ytd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."py_ytd_amt") as "py_ytd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."py_all_ytd_amt") as "py_all_ytd_amt", SUM(dm_ebg_glb_kpi_sum_w_v."end_bal_amt") as "end_bal_amt", SUM(dm_ebg_glb_kpi_sum_w_v."cp_open_bal_amt") as "cp_open_bal_amt", SUM(dm_ebg_glb_kpi_sum_w_v."pq_end_bal_amt") as "pq_end_bal_amt", SUM(dm_ebg_glb_kpi_sum_w_v."cy_open_bal_amt") as "cy_open_bal_amt", SUM(dm_ebg_glb_kpi_sum_w_v."py_end_bal_amt") as "py_end_bal_amt" FROM fin_dmr_ebgdis.dm_ebg_glb_kpi_sum_w_v where 1 = 1 and 1 = 1 AND dm_ebg_glb_kpi_sum_w_v."period_id" = 202302 group by dm_ebg_glb_kpi_sum_w_v."na_level_name", dm_ebg_glb_kpi_sum_w_v."na_level", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv1_prod_list_code", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv3_prod_list_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_lv0_prod_list_en_name", dm_ebg_glb_kpi_sum_w_v."sales_lv2_prod_list_code", dm_ebg_glb_kpi_sum_w_v."period_id", dm_ebg_glb_kpi_sum_w_v."year", dm_ebg_glb_kpi_sum_w_v."month", dm_ebg_glb_kpi_sum_w_v."report_category_cn_name", dm_ebg_glb_kpi_sum_w_v."report_category_en_name", dm_ebg_glb_kpi_sum_w_v."currency_code", dm_ebg_glb_kpi_sum_w_v."exchange_rate_type_cn_name", dm_ebg_glb_kpi_sum_w_v."exchange_rate_type_en_name", dm_ebg_glb_kpi_sum_w_v."report_item_code", dm_ebg_glb_kpi_sum_w_v."report_item_cn_name", dm_ebg_glb_kpi_sum_w_v."report_item_en_name", dm_ebg_glb_kpi_sum_w_v."report_item_type", dm_ebg_glb_kpi_sum_w_v."report_item_flag", dm_ebg_glb_kpi_sum_w_v."region_code", dm_ebg_glb_kpi_sum_w_v."region_cn_name", dm_ebg_glb_kpi_sum_w_v."region_en_name", dm_ebg_glb_kpi_sum_w_v."oversea_flag", dm_ebg_glb_kpi_sum_w_v."repoffice_code", dm_ebg_glb_kpi_sum_w_v."repoffice_cn_name", dm_ebg_glb_kpi_sum_w_v."repoffice_en_name", dm_ebg_glb_kpi_sum_w_v."ebg_focus_cn_name", dm_ebg_glb_kpi_sum_w_v."ebg_focus_en_name", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv0_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv1_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv2_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rnd_team_code", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rd_team_cn_name", dm_ebg_glb_kpi_sum_w_v."lv3_prod_rd_team_en_name", dm_ebg_glb_kpi_sum_w_v."named_account_flag", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_code", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_cn_name", dm_ebg_glb_kpi_sum_w_v."domtc_entps_indu_class_en_name", dm_ebg_glb_kpi_sum_w_v."industry_class_code", dm_ebg_glb_kpi_sum_w_v."industry_class_cn_name", dm_ebg_glb_kpi_sum_w_v."industry_class_en_name", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_code", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_cn_name", dm_ebg_glb_kpi_sum_w_v."sub_industry_class_en_name", dm_ebg_glb_kpi_sum_w_v."focus_industry_cn_name", dm_ebg_glb_kpi_sum_w_v."focus_industry_en_name", dm_ebg_glb_kpi_sum_w_v."sales_mode_code", dm_ebg_glb_kpi_sum_w_v."sales_mode_cn_name", dm_ebg_glb_kpi_sum_w_v."sales_mode_en_name" limit 200
3、【性能分析】
由于语句长时间无法执行完毕,通过其verbose执行计划中的E-rows可以看出,由于较小且去重后行数变化不大,优化器采用了Sort+GroupAgg的聚集方式。

通常情况下,Sort+GroupAgg性能并不如Hashagg,此时,可以通过利用
set enable_sort = off;
或是
+set [gloabal] (enable_sort off)
来避免使用Sort+GroupAgg聚集方式。
补充:Sort+GroupAgg与Hashagg对比
|
Hashagg |
Sort+GroupAgg |
|
|---|---|---|
|
执行方式 |
每行元组根据聚集列散列建立hash表,进行去重比较 |
所有元组排序后进行聚集去重操作 |
|
限制 |
所有聚集列支持hash散列 |
所有聚集列支持排序 |
|
优势 |
通过哈希散列比较可以快速定位到重复元组 |
输出结果保持有序,有利于后续有序操作 |
|
劣势 |
受初始散列桶个数影响较大 |
如果初始集较大,Sort性能较差 |
|
适合使用的情况 |
去重后行数较少的场景 |
相比Hashagg,当去重后行数和输入行数差不多,且输入行数较少时适用 |

从上图中可以看出,调优后语句执行时间下降为22s+,性能大大提高。从performance计划可以看出,原始SQL语句verbose计划中E-rows不准确,导致优化器选择了Sort+GroupAgg聚集方式,从而使得语句执行性能下降。
附件enable_sort-1为调优前verbose执行计划,附件enable_sort-2为调优后performance执行计划
- 附件:enable_sort-1.txt688.04KB
- 附件:enable_sort-2.txt1.57MB
GaussDB(DWS)性能调优:Sort+Groupagg聚集引起的性能瓶颈案例的更多相关文章
- 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写
摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...
- 十八般武艺玩转GaussDB(DWS)性能调优(三):好味道表定义
摘要:表结构设计是数据库建模的一个关键环节,表定义好坏直接决定了集群的有效容量以及业务查询性能,本文从产品架构.功能实现以及业务特征的角度阐述在GaussDB(DWS)的中表定义时需要关注的一些关键因 ...
- 十八般武艺玩转GaussDB(DWS)性能调优:路径干预
摘要:路径生成是表关联方式确定的主要阶段,本文介绍了几个影响路径生成的要素:cost_param, scan方式,join方式,stream方式,并从原理上分析如何干预路径的生成. 一.cost模型选 ...
- 数据库性能调优之始: analyze统计信息
摘要:本文简单介绍一下什么是统计信息.统计信息记录了什么.为什么要收集统计信息.怎么收集统计信息以及什么时候收集统计信息. 1 WHY:为什么需要统计信息 1.1 query执行流程 下图描述了Gau ...
- Java性能调优(一):调优的流程和程序性能分析
https://blog.csdn.net/Oeljeklaus/article/details/80656732 Java性能调优 随着应用的数据量不断的增加,系统的反应一般会越来越慢,这个时候我 ...
- 大厂运维必备技能:PB级数据仓库性能调优
摘要:众所周知,数据量大了之后,性能是大家关注的一点,所以我们在业务开发的时候,特别关注性能,做为一个架构师,必须对性能要了解,要懂.才能设计出高性能的业务系统. 一.GaussDB分布式架构 所谓集 ...
- 第0/24周 SQL Server 性能调优培训引言
大家好,这是我在博客园写的第一篇博文,之所以要开这个博客,是我对MS SQL技术学习的一个兴趣记录. 作为计算机专业毕业的人,自己对技术的掌握总是觉得很肤浅,博而不专,到现在我才发现自己的兴趣所在,于 ...
- SQL Server 列存储性能调优(翻译)
原文地址:http://social.technet.microsoft.com/wiki/contents/articles/4995.sql-server-columnstore-performa ...
- 性能调优:理解Set Statistics IO输出
性能调优是DBA的重要工作之一.很多人会带着各种性能上的问题来问我们.我们需要通过SQL Server知识来处理这些问题.经常被问到的一个问题是:早上这个存储过程运行时间还是可以的,但到了晚上就很慢很 ...
- 在SQL Server 2016里使用查询存储进行性能调优
作为一个DBA,排除SQL Server问题是我们的职责之一,每个月都有很多人给我们带来各种不能解释却要解决的性能问题. 我就多次听到,以前的SQL Server的性能问题都还好且在正常范围内,但现在 ...
随机推荐
- 想让你的代码简洁,试试这个SimpleDateFormat类高深用法
本文分享自华为云社区<从入门到精通:SimpleDateFormat类高深用法,让你的代码更简洁!>,作者:bug菌. 环境说明:Windows 10 + IntelliJ IDEA 20 ...
- 鸿蒙极速入门(六)-加载请求状态管理-LoadState+观察者模式
背景 1.在ArkTS的架构中,没有明确的可管理的加载请求状态的脚手架,在进行网络请求过程中,无法简单的进行交互响应. 2.参考Android中的LoadState写了一个简单的脚手架,以便在日常开发 ...
- moment日期处理类库
Moment 被设计为在浏览器和 Node.js 中都能工作. 安装 npm install moment --save # npm yarn add moment # Yarn 使用 /** * F ...
- 不可复制的PDF转成双层可复制PDF
有些PDF是通过扫描或者虚拟打印机生成的,这些PDF不可复制里边的内容 市面上的工具一般都是收费或者有水印,所以就萌生了自己搞一个的想法: 使用了以下三个开源库 PdfiumViewer PDF预览及 ...
- HTTP 和 RPC 的区别
一句话概括 RPC代表:Feign.Dubbo RPC 主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便. HTTP 代表:RestTemplate.HttpClient HTTP 主 ...
- 单元测试之Mockito+Junit使用和总结
https://www.letianbiji.com/java-mockito/mockito-thenreturn.html Mockito 使用 thenReturn 设置方法的返回值 thenR ...
- 2D物理引擎 Box2D for javascript Games 第七章 子弹和感应器
2D物理引擎 Box2D for javascript Games 第七章 子弹和感应器 你知道 Box2D 可以在每一个时间步中管理刚体间的碰撞并决算它们. 总之,在愤怒的小鸟中制作攻城机器期间,发 ...
- Go 接口:nil接口为什么不等于nil?
Go 接口:nil接口为什么不等于nil? 本文主要内容:深入了解接口类型的运行时表示层. 目录 Go 接口:nil接口为什么不等于nil? 一.Go 接口的地位 二.接口的静态特性与动态特性 2.1 ...
- 持续集成指南:GitHubAction 自动构建+部署AspNetCore项目
前言 之前研究了使用 GitHub Action 自动构建和发布 nuget 包:开发现代化的.NetCore控制台程序:(4)使用GithubAction自动构建以及发布nuget包 现在更进一步, ...
- [WPF]标记扩展(Markup Extension)
XAML是基于XML的语言,其遵循并扩展了XML的语法规则.其中一项扩展就是标记扩展(Markup Extension),比如我们经常使用的绑定Binding和x:Type. 什么是标记扩展 标记扩展 ...