本文分享自华为云社区《GaussDB(DWS) 谓词列analyze揭秘》,作者:SmithCoder。

1. 前言

适用版本:【9.1.0.100(及以上)】

​当前GaussDB(DWS)中存在手动analyze,查询触发的动态analyze,以及后台线程的轮询analyze三种触发形式,其中动态analyze又分为light模式和normal模式,light模式是基于内存存储统计信息,normal模式是存储在系统表里,前者较为轻量,对目标表仅加一级锁。这些analyze默认都是对表全列进行采样,尤其对于大宽表analyze,耗时会比较久,其实很多时候计划生成所需的统计信息列只占一部分,如果只对这部分列进行采样计算,将会大大节省analyze的时间。因此GaussDB(DWS)引入了谓词列analyze。

2.原理介绍

​analyze的时候主要耗时在采样数据,对于非定长列如varchar,其统计信息的计算也耗时,耗时肯定随着表的列数增加而变长。谓词列analyze会在查询阶段对谓词列进行识别收集,当触发动态analyze,会只选择采样谓词列,手动谓词列analyze也会只采样谓词列部分。

谓词列通指于 WHERE 条件,join条件,group by中涉及到的列,更广义的是指所有需要用于计划生成需要统计信息列的列。

识别到的谓词列包含:

  • 条件谓词列

如比较(=,>,<),like, between,is,in, having,join on,MERGE on后面的列

  • 排序分组列

如group by, order by, distinct, over partition/order by列,union /minus列

  • 子查询引用列

等值条件列为一个子查询,子查询的对应的输出列;

cte中的一个列被外层引用为谓词列;

视图中的列被外层应用为谓词列;

agg列

  • 索引列

列建立了索引,相应的列也会被收集识别

  • 分布列

如果表建立了hash分别列,分布列也收集识别

3.使用介绍

下面分别介绍谓词列analyze支持两种形式:

  1. 动态采样谓词列analyze

  2. 手动谓词列analyze

3.1谓词列的guc控制

谓词列analyze的开启由guc参数analyze_predicate_column_threshold控制

参数说明:控制是否开启谓词列ANALYZE及限定支持的最小列数。该参数仅9.1.0.100及以上集群版本支持。

参数类型:SIGHUP

取值范围:整型,0~10000

  • 0表示关闭谓词列ANALYZE,不会收集谓词列以及对谓词列进行ANALYZE。

  • 大于0表示开启谓词列收集功能,且仅对列数大于等于此值的表进行谓词列ANALYZE。

默认值:10

3.2.动态采样谓词列analyze

前提:动态采样谓词列analyze只支持light模式

查询的时候会进行谓词列的识别,如果有新的谓词列或者修改计数达到,则会触发动态采样,会把新识别的和已有的谓词列进行采样计算 统计信息。

下面是按照analyze_predicate_column_threshold=1举例,计划中RunTime Analyze Information部分会打印出analyze的表和列信息。

create table t1(a int, b int, c int);
create table t2(a int, b int, c int);
set enable_fast_query_shipping=off;
set autoanalyze_mode=light;
-- 首次会收集所有列的统计信息
test=# explain select * from t1;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+------------------------------+--------+----------+---------+---------
1 | -> Streaming (type: GATHER) | 20 | | 12 | 16.10
2 | -> Seq Scan on t1 | 20 | 1MB | 12 | 10.10 RunTime Analyze Information
------------------------------------------------------------------------------------------------------------------------------
light runtime analyze on "public.t1" times:9.245ms, stats:sync, change:0(0 in xact), alive:0.000000, threshold:50.000000 ====== Query Summary =====
-------------------------------
System available mem: 4710400KB
Query Max mem: 4710400KB
Query estimated mem: 1024KB insert into t1 select generate_series(1, 100), 1; -- 修改计数达到,收集到了a,b两个谓词列,触发动态采样
test=# explain select * from t1 where a=b;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+------------------------------+--------+----------+---------+---------
1 | -> Streaming (type: GATHER) | 1 | | 12 | 7.62
2 | -> Seq Scan on t1 | 1 | 1MB | 12 | 1.62 RunTime Analyze Information
-------------------------------------------------------------------------------------------------------------------------------
light runtime analyze on "public.t1(a,b)" times:9.774ms, stats:sync, change:100(0 in xact), alive:100.000000, threshold:50 Predicate Information (identified by plan id)
---------------------------------------------
2 --Seq Scan on t1
Filter: (a = b) ====== Query Summary =====
-------------------------------
System available mem: 4710400KB
Query Max mem: 4710400KB
Query estimated mem: 1024KB
(19 rows) -- 修改计数达到后查询,查询下面的语句,会分别收集表t1,t2对应的谓词列
test=# explain select t1.* from t1 join t2 on t1.b=t2.c where t1.a=t2.a;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+--------------------------------------+--------+----------+---------+---------
1 | -> Streaming (type: GATHER) | 2 | | 12 | 21.55
2 | -> Hash Join (3,5) | 2 | 1MB | 12 | 15.55
3 | -> Streaming(type: BROADCAST) | 400 | 2MB | 8 | 10.93
4 | -> Seq Scan on t2 | 200 | 1MB | 8 | 2.00
5 | -> Hash | 200 | 16MB | 12 | 2.00
6 | -> Seq Scan on t1 | 200 | 1MB | 12 | 2.00 RunTime Analyze Information
-------------------------------------------------------------------------------------------------------------------------------
light runtime analyze on "public.t1(a,b)" times:11.031ms, stats:sync, change:100(0 in xact), alive:200.000000, threshold:60
light runtime analyze on "public.t2(a,c)" times:8.571ms, stats:sync, change:100(0 in xact), alive:200.000000, threshold:60 Predicate Information (identified by plan id)
----------------------------------------------------
2 --Hash Join (3,5)
Hash Cond: ((t2.c = t1.b) AND (t2.a = t1.a)) ====== Query Summary =====
-------------------------------
System available mem: 4710400KB
Query Max mem: 4710400KB
Query estimated mem: 4388KB -- 遇到新的谓词列且该列没有统计信息也会触发
test=# explain select * from t1 where c=1;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------
id | operation | E-rows | E-memory | E-width | E-costs
----+------------------------------+--------+----------+---------+---------
1 | -> Streaming (type: GATHER) | 1 | | 12 | 8.25
2 | -> Seq Scan on t1 | 1 | 1MB | 12 | 2.25 RunTime Analyze Information
-------------------------------------------------------------------------------------------------------------------------------
light runtime analyze on "public.t1(a,b,c)" times:10.063ms, stats:sync, change:0(0 in xact), alive:200.000000, threshold:70

3.3手动谓词列

语法:analyze (predicate) tablename;

执行后,只会对当前为止收集到的谓词列进行采样,最后在查询业务稳定后使用;

3.4谓词列管理

  • 查询谓词列

通过函数pg_stat_get_predicate_columns可以查询当前表有哪些谓词列

test=# select pr.attnum,pa.attname from pg_catalog.pg_stat_get_predicate_columns('t1'::regclass) pr left join pg_attribute pa on pa.attrelid='t1'::regclass and pa.attnum = pr.attnum;
attnum | attname
--------+---------
1 | a
2 | b
(2 rows)
  • 清空谓词列

通过函数select * from pg_catalog.pg_stat_get_predicate_columns(‘t1_3’::regclass);可以清空表的谓词列,一般用于谓词列太多或者过期的情况去清空重建

4.总结

9.1.0.100版本中autoanalyze(light模式)和谓词列默认是开启的,用户无需感知。对于频繁大量更新和查询场景,此前的动态采样可能会耗时,影响查询业务,新增谓词列后会减少analyze的耗时,特别对大宽表场景耗时优化是可观的。

5. 参考文档

一文读懂analyze使用【这次高斯不是数学家】 https://bbs.huaweicloud.com/blogs/354294

一文读懂autoanalyze使用【这次高斯不是数学家】 https://bbs.huaweicloud.com/blogs/354298

华为开发者空间,汇聚鸿蒙、昇腾、鲲鹏、GaussDB、欧拉等各项根技术的开发资源及工具,致力于为每位开发者提供一台云主机、一套开发工具及云上存储空间,让开发者基于华为根生态创新。点击链接,免费领取您的专属云主机。

点击关注,第一时间了解华为云新鲜技术~

优化大宽表查询性能,揭秘GaussDB(DWS) 谓词列analyze的更多相关文章

  1. android app性能优化大汇总(内存性能优化)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 写在最前: 本文的思路主要借鉴了2014年AnDevCon开发者大会的一个演讲PPT,加上 ...

  2. mysql 优化海量数据插入和查询性能

    对于一些数据量较大的系统,数据库面临的问题除了查询效率低下,还有就是数据入库时间长.特别像报表系统,每天花费在数据导入上的时间可能会长达几个小时或十几个小时之久.因此,优化数据库插入性能是很有意义的. ...

  3. 提升50%!Presto如何提升Hudi表查询性能?

    分享一篇关于使用Hudi Clustering来优化Presto查询性能的talk talk主要分为如下几个部分 演讲者背景介绍 Apache Hudi介绍 数据湖演进和用例说明 Hudi Clust ...

  4. Oracle Spatial分区应用研究之一:分区与分表查询性能对比

    1.名词解释 分区:将一张大表在物理上分成多个分区,逻辑上仍然是同一个表名. 分表:将一张大表拆分成多张小表,不同表有不同的表名. 两种数据组织形式的原理图如下: 图 1分表与分区的原理图 2.实验目 ...

  5. spark生成大宽表的parquet性能优化

    1.  背景介绍 将一份数据量很大的用户属性文件解析成结构化的数据供查询框架查询剖析,其中用户属性包含用户标识,平台类型,性别,年龄,学历,兴趣爱好,购物倾向等等,大概共有七百个左右的标签属性.为了查 ...

  6. 数据库优化之锁表查询 (Sql Server)

    查询锁表语句 select request_session_id spid,DB_NAME(resource_database_id) databaseName, OBJECT_NAME(resour ...

  7. mysql select limit 大数据量查询 性能终极提升方法

    还是广告位 我们的使用mysql的时候总是想当然的使用 select × from tables where a>0 order by id desc limit 500000,200 当我们真 ...

  8. 十八般武艺玩转GaussDB(DWS)性能调优(三):好味道表定义

    摘要:表结构设计是数据库建模的一个关键环节,表定义好坏直接决定了集群的有效容量以及业务查询性能,本文从产品架构.功能实现以及业务特征的角度阐述在GaussDB(DWS)的中表定义时需要关注的一些关键因 ...

  9. MySQL查询性能优化(精)

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

  10. 170727、MySQL查询性能优化

    MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下 ...

随机推荐

  1. OOP的核心思想

    1. 封装 既是信息封装,把一些信息进行封装成对象,只保留部分接口和方法与外部联系,能有效避免程序间相互依赖,实现代码模块间松藕合 : 2. 继承 子类自动继承父类的属性和方法,继承实现了代码的重用性 ...

  2. js递归遍历树形结构数据,获取所有数组id集合

    function getAllIds(tree, result) { //遍历树 获取id数组 for (const i in tree) { result.push(tree[i].id); // ...

  3. 什么是 Ajax,Ajax 的原理,Ajax 都有哪些优点和缺点

    ajax是异步的js和xml,是一种创建交互式网页的开发技术,是和服务器进行异步通讯的技术 : 核心就是使用XMLHttpRequest向服务器发送请求获取数据 : 优点: 页面不需要刷新,用户体验良 ...

  4. python的十大数据结构之堆队列heapq(heap queue)

    heap queque(堆队列),是一个完全二叉树,并且满足一个条件:每个节点(叶节点除外)的值都大于等于(或小于等于)它的子节点.提供了构建小顶堆的方法和一些小顶堆的基本操作方法(如入堆.出堆等), ...

  5. nicegui太香了,跨平台开发和跨平台运行--使用Python+nicegui实现系统布局界面的开发

    在现今国产化浪潮的驱动下,跨平台或者缩小范围说基于国产化Linux或者基于国产鸿蒙系统的开发才是未来的趋势了,风口浪尖上,我们开发人员也只能顺势而为,本篇随笔介绍在Python开发中,使用使用Pyth ...

  6. 云原生周刊 | 使用 K8s 可视化工具集来调试业务 | 2023-1-30

    开源项目推荐 k8z k8z 意在 K8s 业务层面,提供一个方便好用的 K8s 集群可视化工具集.目前包含以下功能: 终端:连接到集群任意 Pod 容器上,方便调试 Tcpdump:对集群内容器进行 ...

  7. 掀起云端革命!ToDesk云电脑与传统PC电脑的差异分析

    在科技日新月异的今天,传统PC电脑的市场地位正悄然发生变化.随着云计算技术的不断成熟与普及,云电脑逐渐走进大众视野,不同于传统PC电脑的高昂的成本和易退化的硬件性能,云电脑正以其轻成本高性能的优势吸引 ...

  8. Machine Learning Week_1 Introduction 5-8

    目录 1.5 Vedio: Supervised Learning unfamiliar words 1.6 Reading: Supervised Learning unfamiliar words ...

  9. myBatis插入操作获取不到返回的自增id问题

    myBatis插入操作后想返回自增 id 有多种方式 其中一种使用率较高的就是: 在<insert></insert> 标签中添加 useGeneratedKeys 和 key ...

  10. DHorse v1.6.0 发布,基于 k8s 的发布平台

    版本说明 新增特性 支持Codeup(阿里云云效)代码仓库: 支持环境的自动部署: 优化特性 管理员角色部署环境部需要审批: 优化页面展示: 升级指南 升级指南 DHorse介绍 DHorse是一个轻 ...