2个场景实例讲解GaussDB(DWS)基表统计信息估算不准的处理方案
摘要:通过2个实例场景讲解GaussDB(DWS)运维解决方案。
本文分享自华为云社区《GaussDB(DWS)运维 -- 基表统计信息估算不准的常见场景及处理方案》,作者:譡里个檔。
场景1:基表过滤字段存在的隐式类型时,基表行数估算偏小
这种场景绝大部分场景DWS能够处理,但是如果隐式类型转后的结果与统计信息中的字段枚举值的表达式不一样,就会导致估算的严重偏差
原始SQL如下
SELECT * FROM dmgrpdi.dwl_inv_res_rpt_ci_grp_f WHERE period_id=202212 AND source_flag=1;
对应的执行计划
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+------------------------------------------------------------------+--------+----------+---------+-----------
1 | -> Row Adapter | 14160 | | 717 | 680025.43
2 | -> Vector Streaming (type: GATHER) | 14160 | | 717 | 680025.43
3 | -> Vector Partition Iterator | 14160 | 1MB | 717 | 678241.33
4 | -> Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f | 14160 | 1MB | 717 | 678241.33
Predicate Information (identified by plan id)
-------------------------------------------------------------------------------
3 --Vector Partition Iterator
Iterations: 1
4 --Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f
Filter: ((period_id = 202212::numeric) AND ((source_flag)::bigint = 1))
Pushdown Predicate Filter: (period_id = 202212::numeric)
Partitions Selected by Static Prune: 36
发现source_flag字段上存在隐式类型转换,查询字段source_flag的统计信息
postgres=# SELECT most_common_vals,most_common_freqs, histogram_bounds FROM pg_stats WHERE tablename = 'dwl_inv_res_rpt_ci_grp_f' AND attname = 'source_flag';
most_common_vals | most_common_freqs | histogram_bounds
------------------+-----------------------------------+------------------
{01,02,04,03} | {.440034,.241349,.217413,.101089} | {05,06}
(1 row)
发现隐式类型转后的结果(1)与统计信息中的字段枚举值('01')的表达式不一样
处理方案:修改过滤条件,禁止类型转换,并且使用正确的常量值书写过滤条件
如上SQL语句中的source_flag=1修改为source_flag='01',修改后SQL语句如下
SELECT * FROM dmgrpdi.dwl_inv_res_rpt_ci_grp_f WHERE period_id=202212 AND source_flag='01';
查询新语句的执行计划
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+------------------------------------------------------------------+-----------+----------+---------+-----------
1 | -> Row Adapter | 108359075 | | 717 | 480542.98
2 | -> Vector Streaming (type: GATHER) | 108359075 | | 717 | 480542.98
3 | -> Vector Partition Iterator | 108359075 | 1MB | 717 | 478758.88
4 | -> Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f | 108359075 | 1MB | 717 | 478758.88
Predicate Information (identified by plan id)
-------------------------------------------------------------------------------------------------
3 --Vector Partition Iterator
Iterations: 1
4 --Partitioned CStore Scan on dwl_inv_res_rpt_ci_grp_f
Filter: ((period_id = 202212::numeric) AND (source_flag = '01'::text))
Pushdown Predicate Filter: ((period_id = 202212::numeric) AND (source_flag = '01'::text))
Partitions Selected by Static Prune: 36
场景2:基表在多列组合主键上过滤时,基表行数估算偏大
这种场景是因为DWS对基表上多个过滤条件之间采取弱相关性处理,当多个过滤条件是主键时,可能导致结果集估算偏大。
原始SQL如下
SELECT * FROM mca.mca_period_rate_t mca_rate2
WHERE period_number = '202208' AND from_currency_code = 'RMB' AND to_currency_code = 'USD'
执行信息如下
id | operation | A-time | A-rows | E-rows | Peak Memory | E-memory | A-width | E-width | E-costs
----+------------------------------------------------------+--------------------+--------+--------+-------------+----------+---------+---------+----------
1 | -> Row Adapter | 444.735 | 1 | 2033 | 227KB | | | 321 | 22601.41
2 | -> Vector Streaming (type: GATHER) | 444.720 | 1 | 2033 | 873KB | | | 321 | 22601.41
3 | -> CStore Scan on mca_period_rate_t mca_rate2 | [435.167, 435.167] | 1 | 2033 | [5MB, 5MB] | 1MB | | 321 | 22427.41
Predicate Information (identified by plan id)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 --CStore Scan on mca_period_rate_t mca_rate2
Filter: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))
Rows Removed by Filter: 425812
Pushdown Predicate Filter: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))
可以发现基表mca.mca_period_rate_t的行数估算严重偏大。
使用如下SQL语句查看表mca.mca_period_rate_t的定义
SELECT pg_get_tabledef('mca.mca_period_rate_t'::regclass);
查询表mca.mca_period_rate_t定义
SELECT pg_get_tabledef('mca.mca_period_rate_t');
SET search_path = mca;
CREATE TABLE mca_period_rate_t (
seq numeric NOT NULL,
period_number character varying(10) NOT NULL,
from_currency_code character varying(20) NOT NULL,
to_currency_code character varying(20) NOT NULL,
begin_rate numeric(35,18),
end_rate numeric(35,18),
avg_rate numeric(35,18),
creation_date timestamp(0) without time zone NOT NULL,
created_by numeric NOT NULL,
last_update_date timestamp(0) without time zone,
last_updated_by numeric,
rmb_begin_rate numeric(35,18),
usd_begin_rate numeric(35,18),
rmb_end_rate numeric(35,18),
usd_end_rate numeric(35,18),
rmb_avg_rate numeric(35,18),
usd_avg_rate numeric(35,18),
crt_cycle_id numeric,
crt_job_instance_id numeric,
last_upd_cycle_id numeric,
upd_job_instance_id numeric,
cdc_key_id character varying(128) DEFAULT sys_guid(),
end_rate2 numeric(35,18),
avg_rate2 numeric(35,18),
last_period_end_rate numeric(35,18)
)
WITH (orientation=column, compression=low, colversion=2.0, enable_delta=false)
DISTRIBUTE BY REPLICATION
TO GROUP group_version1;
CREATE UNIQUE INDEX mca_period_rate_u1 ON mca.mca_period_rate_t USING cbtree (period_number, from_currency_code, to_currency_code) TABLESPACE pg_default;
发现 (period_number, from_currency_code, to_currency_code) 为组合的唯一索引。
处理方案:对组合索引列收多列统计信息
注意此种方案只适用在基表比较小的情况下。因为多列统计信息需要使用百分比采样的方式计算统计信息,当表比较大时,统计信息计算耗时回很长。
针对如上查询语句执行如下语句收集(period_number, from_currency_code, to_currency_code) 多列统计信息
ANALYZE mca.mca_period_rate_t((period_number, from_currency_code, to_currency_code));
收集多列统计信息之后,基表的行数估算恢复正产
id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs
----+-------------------------------------------------------------------------------------+--------------------+--------+--------+-------------+---------+---------+---------
1 | -> Row Adapter | 195.504 | 1 | 1 | 227KB | | 321 | 675.14
2 | -> Vector Streaming (type: GATHER) | 195.491 | 1 | 1 | 873KB | | 321 | 675.14
3 | -> CStore Index Scan using mca_period_rate_u1 on mca_period_rate_t mca_rate2 | [164.344, 164.344] | 1 | 1 | [5MB, 5MB] | | 321 | 501.14
Predicate Information (identified by plan id)
----------------------------------------------------------------------------------------------------------------------------------------------------------
3 --CStore Index Scan using mca_period_rate_u1 on mca_period_rate_t mca_rate2
Index Cond: (((period_number)::text = '202208'::text) AND ((from_currency_code)::text = 'RMB'::text) AND ((to_currency_code)::text = 'USD'::text))
2个场景实例讲解GaussDB(DWS)基表统计信息估算不准的处理方案的更多相关文章
- 一文详解GaussDB(DWS) 的并发管控和内存管控
摘要:DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制. 本文分享自华为云社区<GaussDB(DWS) 并发管控&内存管控>,作者: fight ...
- 详解GaussDB(DWS) explain分布式执行计划
摘要:本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点. 前言 执行计划(又称解释计划)是数据库执行SQL语句的具体步骤,例如通过索引还是全表扫描访问表中的 ...
- 十八般武艺玩转GaussDB(DWS)性能调优(三):好味道表定义
摘要:表结构设计是数据库建模的一个关键环节,表定义好坏直接决定了集群的有效容量以及业务查询性能,本文从产品架构.功能实现以及业务特征的角度阐述在GaussDB(DWS)的中表定义时需要关注的一些关键因 ...
- 从数据仓库双集群系统模式探讨,看GaussDB(DWS)的容灾设计
摘要:本文主要是探讨OLAP关系型数据库框架的数据仓库平台如何设计双集群系统,即增强系统高可用的保障水准,然后讨论一下GaussDB(DWS)的容灾应该如何设计. 当前社会.企业运行当中,大数据分析. ...
- GaussDB(DWS)应用实践丨负载管理与作业排队处理方法
摘要:本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务:或者在作业 ...
- 十八般武艺玩转GaussDB(DWS)性能调优:SQL改写
摘要:本文将系统介绍在GaussDB(DWS)系统中影响性能的坏味道SQL及SQL模式,帮助大家能够从原理层面尽快识别这些坏味道SQL,在调优过程中及时发现问题,进行整改. 数据库的应用中,充斥着坏味 ...
- 十八般武艺玩转GaussDB(DWS)性能调优:路径干预
摘要:路径生成是表关联方式确定的主要阶段,本文介绍了几个影响路径生成的要素:cost_param, scan方式,join方式,stream方式,并从原理上分析如何干预路径的生成. 一.cost模型选 ...
- GaussDB(DWS)中共享消息队列实现的三大功能
摘要:本文将详细介绍GaussDB(DWS)中共享消息队列的实现. 本文分享自华为云社区<GaussDB(DWS)CBB组件之共享消息队列介绍>,作者:疯狂朔朔. 1)共享消息队列是什么? ...
- 详解GaussDB(DWS) 资源监控
摘要:本文主要着重介绍资源池资源监控以及用户资源监控. 本文分享自华为云社区<GaussDB(DWS)资源监控之用户.队列资源监控>,作者: 一只菜菜鸟. GaussDB(DWS)资源监控 ...
- 一文详解数仓GaussDB(DWS) 函数出参带出方式
摘要:本文主要讲解DWS函数出参带出方式. 本文分享自华为云社区<GaussDB(DWS)功能 -- 函数出参 #[玩转PB级数仓GaussDB(DWS)]>,作者:譡里个檔 . DWS的 ...
随机推荐
- 设计模式(二十八)----综合应用-自定义Spring框架-Spring简单回顾
1 spring使用回顾 自定义spring框架前,先回顾一下spring框架的使用,从而分析spring的核心,并对核心功能进行模拟. 数据访问层.定义UserDao接口及其子实现类 public ...
- nodsjs POST请求
PHP 遇到问题: 1.跨域问题 报failed to load response data:no data fond for response with give header("Cont ...
- 方差分析1—单因素方差分析(R语言)
方差分析是由英国著名统计学家:R.A.Fisher推导,也叫F检验,用于多个样本间均数的比较(分析类别变量.有序变量).当包含的因子是解释变量时,关注的重点通常会从预测转向组别差异的分析.方差分析是一 ...
- 高尔顿钉板的统计意义—R实现
提到高尔顿,人们总是把他和钉板实验联系在一起,偶尔也会有人提及他是达尔文的表弟.实际上,作为维多利亚时代的人类学家.统计学家.心理学家和遗传学家,同时又是热带探险家.地理学家.发明家.气象学家,高尔顿 ...
- 6步带你用Spring Boot开发出商城高并发秒杀系统
摘要:本博客将介绍如何使用 Spring Boot 实现一个简单的商城秒杀系统,并通过使用 Redis 和 MySQL 来增强其性能和可靠性. 本文分享自华为云社区<Spring Boot实现商 ...
- Let's Encrypt 泛域名证书申请
泛域名 泛域名证书又名通配符证书是SSL证书中的其中一种形式,一般会以通配符的形式(如:*.domain.com)来指定证书所要保护的域名. OV证书和DV证书都会有通配符的域名形式提供,而EV证书一 ...
- kubernetes(k8s) 中安装kuboard面板
kubernetes(k8s) 中安装kuboard面板 01 - 背景及安装 Kuboard 是一款专为 Kubernetes 设计的免费管理界面,兼容 Kubernetes 版本 1.13 及以上 ...
- Android HAL机制的深入理解及在Linux上移植和运行的一个好玩的HAL小例子
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 环境说明 Ubuntu 18.04.x 前言 近一年来, ...
- redis 基于 漏斗算法 实现对 api 的限流
漏斗算法 漏桶算法的原理: 漏桶有一定的容量,给漏桶注水,当单位时间内注入水量大于流出水量,漏桶内积累的水就会越来越多,直到溢出. 就好比大批量请求访问nginx相当于注水,nginx根据配置按照固定 ...
- Ubuntu Server搭建个人服务器
Ubuntu Server20.04.5 LTS [参考资料] Ubuntu官方地址:https://www.ubuntu.com/ Ubuntu论坛地址:https://ubuntuforums.o ...