GaussDB(DWS) analyze使用指南8.2.0及以上版本
一、功能介绍
手动采样:用户在作业中,手动发起的显示analyze。
轮询采样:autovacuum后台线程,轮询发起的analyze。
动态采样:查询时,优化器触发的runtime analyze。
一键最优
autovacuum = on --启动autovacuum线程,开启轮询采样
autovacuum_analyze_threshold = 50 --设置analyze触发阈值,至少修改50条
autovacuum_analyze_scale_factor = 0.1 --设置analyze触发阈值,至少修改10%
autoanalyze = on --开启动态采样
autoanalyze_mode = 'light' --启用light模式动态采样
analyze_stats_mode = 'dynamic' --自适应选择内存或临时表收集统计信息
enable_extrapolation_stats = on --开启统计信息推算
random_function_version = 1 --使用随机性更好的random函数
820新安装版本已按上述参数配置,升级到820版本的集群,建议按上述配置修改。
功能清单
1. 支持“database, schema, table, column”四个级别收集统计信息。
2. 支持“手动采样”,“后台轮询采样”和“优化器动态采样”三种采样方式。
3. 支持“系统级”和“表级”设置自动触发阈值,自动采样方式和采样大小。
4. 支持“多列统计信息”,需要以临时采样表方式。
5. 支持“统计信息导入导出”,快速收集现场统计信息。
6. 支持“采样大小”自适应,自动提高大表采样率。
7. 支持“计算模型”自适应,自动选择样本放内存还是下盘。
8. 支持“采样模型”可配置,不提高采样大小,增强统计信息准确性。
9. 支持“CN节点故障”,先在当前CN计算统计信息,故障恢复后再进行全局同步。
10.支持“负载均衡场景”,插入和查询不在同一CN触发动态采样。
11.支持“统计信息推理”,统计信息失效时能根据历史统计信息自动推算。
功能调整
- default_statistics_target参数含义还原
原含义:未指定列级采样大小时的全局默认采样大小。
调整前:>0时列级参数优先级高于全局参数;<0时全局参数优先级高于列级,且跟百分比采样和多列统计信息计算强制绑定。
调整后:
a. 优先级都是列级参数高于全局参数,且仅用于控制采样大小。
b. 新增analyze_stats_mode控制计算模型,选择内存还是临时采样表方式计算统计信息。
c. 多列统计信息使用更方便。已注册多列统计信息时自动走临时采样表方式,未注册但analyze多列时提示去注册多列统计信息或设置使用临时采样表方式计算统计信息。
2. analyze内存控制参数调整
使用work_mem控制改为使用maintenance_work_mem控制。
work_mem: 仅用于控制查询中间结果集的静态内存管控。
maintenance_work_mem:用于analyze, vacuum, index这几个数据维护功能的内存管控。
二、手动采样
https://bbs.huaweicloud.com/blogs/354294
三、轮询采样
https://bbs.huaweicloud.com/blogs/354298
后台多个autovacuum线程并发的轮询检查所有表,看哪些表全局修改量达到阈值,然后触发analyze。
配置方法
autovacuum = on --启动后台autovacuum维护线程
autovacuum_analyze_threshold = 50 --表触发analyze的最小修改量,建议改成50
autovacuum_analyze_scale_factor = 0.1 --表触发analyze时的修改百分比,建议改成0.1
autovacuum mode --设置autovacuum维护线程的运行作业
autovacuum_naptime --后台autovacuum维护线程轮询间隔
autovacuum_max_workers --同时运行的autovacuum维护线程的最大数量
前三个参数,按建议值检查并设置;其它参数使用默认值即可。
约束限制
- 不支持临时表,因为无法看见session级数据。
- 不支持事务内数据统计,因只能看见已提交数据。
- 采样大小默认30000,可全局或表级提高采样率。
- 等锁时间2s,为控制对轮询时间影响,2S无法得到锁则立即放弃analyze,下轮再触发。
- 锁冲突,analyze时加四级锁,当与前台业务发生死锁时,自动杀掉后台线程。
四、动态采样
查询时,优化器先检查表是否需要收集统计信息并触发runtime analyze,再生成最优执行计划。
配置方法
autoanalyze = on --开启runtime analyze
autoanalyze_mode = 'light' --设置runtime analyze运行模式,建议light
autoanalyze_cache_num = 10000 --设置light模式下,内存最大缓存统计信息的表的个数
约束限制
采样大小:30000,为控制对查询的影响,使用最小的采样率,保证统计信息基本可信。
等锁时间:2s,为控制对查询的影响,2S无法得到锁则立即放弃analyze,查询继续执行。下次再触发。
异常处理:查询触发的analyze执行异常会被自动捕获并日志输出原因,不影响查询继续执行。
normal模式
- 优化器触发analyze将统计信息写入系统表,需要对目标表加四级锁。
- normal动态采样和轮询采样,只要有一个触发后另一个就不需再触发。
并发与冲突
- 长事务导致堵塞
为保证事务隔离级别,锁要到事务(包括:显示begin/end, 匿名块,存储过程)提交时才能释放。事务内触发动态采样,会长时间持有表上四级锁。
问题风险:四级锁与四级锁及以上的锁冲突,因此会堵塞相同表上的analyze,vacuum和DDL语句。
解决办法:多个事务块并发处理同一张表时,不要使用动态采样,不然会因等锁而串行执行。
2. 查询本身时间长且触发动态采样,导致分区的数据加工被堵塞。
问题风险:analyze会对所有分区都加四级锁,因此会堵塞alter table truncate partition操作。
解决办法:设置object_mtime_record_mode='disable_truncate, disable_partition'可以让analyze提前释放分区上的锁,这样就可以与alter table truncate partition并行。
3.不同查询先后触发不同表analyze导致统计信息收集失败
A查询先触发T1表的动态采样,然后触发T2表的动态采样。拿了T1表的四级锁,申请T2表的四级锁。
B查询先触发T2表的动态采样,然后触发T1表的动态采样。拿了T2表的四级锁,申请T1表的四级锁。
问题风险:导致死锁
解决办法:无需处理,申锁2S会自动超时,自动放弃动态采样。下次查询时再触发。
4.轮询采样与动态采样并发
a. 数据加工完未立即查询数据
b. 轮询采样已经开始执行,此时查询触发动态采样,动态采样会跳过
问题风险:动态采样跳过导致当前查询无最新统计信息。
解决办法:数据加工完立即查询数据或手动执行analyze。
light模式
- 优化器触发analyze将统计信息写入内存,对目标表仅加一级锁,像查询一样轻量。
- light动态采样不会清理表修改计数,轮询采样会再次触发,并清理内存统计信息。
并发与冲突
1. 仅加一级锁,多个查询可以同时触发同一张表的动态采样,都保证有最新统计信息。
2. 因查询本身也加一级锁,所以动态采样也等同于查询,没有锁升级。
3. 动态采样时,不向FirstCN加锁,在其它CN上也不用加锁。
4. 动态采样时,因只读分区数据,可以提前释放分区锁,不用等事务提交。
所以,light模式的动态采样,解决了各种四级锁冲突问题,推荐使用light模式。
五、采样大小自适应
采样大小
默认所有表都采用30000(基于一些理论和实践论证)大小的采样率,确保了大多数情况下统计信息基本可用。但是一些极端情况下需要手动调整表的采样大小。
1. 表数据特征分布不均匀(数据轮询重复,重复倾斜严重等)。
2. 列存为了控制IO,采集部分CU,样本扎堆儿集中在部分CU里。
为了减轻用户去识别这些问题的难度,我们支持了自适应采样大小。
配置方法
default_statistics_target = -0.01
--1. 建议按表大小万分之一计算采样大小,请根据实际情况评估
--2. 是否需要提高采样率与数据特征相关,和表大小无直接关系
--3. 请根据analyze耗时,和统计信息是否导致SQL性能差,进行调整。
正数表示按固定采样大小采样。采样大小= 参数值*300
负数表示按百分比计算采样大小。采样大小 = 表大小 * (-1)*参数值/100
程序内部强制设置最小采样为30000,因此低于30000的设置无效。
3亿 * 0.01% = 30000,因此设置-0.01时只有大于3亿的表才能自适应提供采样率。
注:历史版本default_statistics_target设置负数时,还表示强制使用临时表采样表的方式计算统计信息,也叫“百分比采样”。现在仅表示采样大小。
default_statistics_target实际含义是列的缺省采样大小。列级设置采样大小时,取所有列最大采样大小作为表的采样大小。可以通过ALTER TABLE设置列级采样大小
ALTER TABLE table_name ALTER column_name SET STATISTICS 200; --把采样大小调整为60000
ALTER TABLE table_name ALTER column_name SET STATISTICS PERCENT 2; --把采样大小调整为2%
select attstattarget from pg_class c,pg_attribute a where attrelid=c.oid and c.oid='schema.tableName'::regclass and attnum>0;
-1 表示未设置,使用全局default_statistics_target的值。
0 表示该列不进行采样
>0 表示按固定采样大小
[-1,0) 表示按百分比进行采样
提高采样率会采集更多样本,CPU和IO消耗增加,导致analyze执行时间线性增长。
内存限制
采样越多就会占用更多的内存,我们使用maintenance_work_mem限制analyze的内存使用。
采样大小超过该内存限制后自动降低采样率,通过“计算模式自适应”可不影响采样大小。
六、计算模式自适应
我们支持两种统计信息计算模式:“基于内存的统计信息计算”和“基于临时采样表的统计信息计算”。
基于内存的统计信息计算
将采集的数据样本放入到内存,并在内存中进行统计信息的计算。
CN和DN端的采样大小都受限于maintenance_work_mem。
基于临时采样表的统计信息计算
将采集的数据样本放入到临时创建的样本表中,使用SQL语句计算统计信息。
CN的采样大小不受限;DN端的采样大小受限于maintenance_work_mem。
配置方法
analyze_stats_mode = dynamic --推荐dynamic模式
memory: 强制使用“基于内存的统计信息计算”,无法计算多列统计信息。
sample_table:强制使用“基于临时采样表的统计信息计算”。不支持临时表,所以临时表时会走memory方式。
dynamic:自适应选择统计信息计算方式。CN端样本大小 < maintenance_work_mem,使用memory方式,否则使用sample_table方式。
约束限制
样本较少时使用memory方式性能好;样本较多时使用sample_table方式性能好。
所以30000及条以下时,我们强制使用memory方式,不受限于maintenance_work_mem。
样本较多时使用临时采样表方式性能更优,因此推荐使用自适应的方式。
七、多列统计信息
因只有使用“基于临时采样表的统计信息计算”的方式才能计算多列统计信息,历史版本要求”default_statistics_target设置为负数时才能计算多列统计信息“,现在无此限制。
a. 已注册多列统计信息,会强制使用“基于临时采样表的统计信息计算”的方式。
b. 未注册多列统计信息,但analyze多列,会提示设置临时采样表方式收集统计信息。
c. 临时表不支持多列统计信息计算。
上述约束,以后开发中都可以去掉。
八、采样模型增强
用最少的样本满足统计信息质量,一直是我们努力的方向。因此我们支持了多种采样模型。
配置方法
analyze_sample_mode = 2
0:使用默认的蓄水池采样模型
1:使用优化的蓄水池采样模型,提升统计信息准确性
2:使用自研的range采样模型,提升执行性能和统计信息准确性,只对列存有效。
九、统计信息推算
查询匹配数据已经存在,但未在统计信息中时的一个cost估算优化。可在统计信息收集不及时的情况下保证计划尽可能最优。
配置方法
enable_extrapolation_stats = on
十、自动采样方式控制
支持表级控制“统计信息自动收集模式”。也可以锁定统计信息。
alter table lineitem set (analyze_mode='backend'); --设置表只做后台线程异步轮询的analyze
alter table lineitem set (analyze_mode='runtime'); --设置表只做前台线程动态采样的analyze
alter table lineitem set (analyze_mode='frozen'); --设置表禁止做所有形式的analyze
alter table lineitem set (analyze_mode='all'); --恢复表analyze模式的默认行为
十一、随机函数增强
random_function_version 控制analyze在进行数据采样时选取的random函数版本。
- 0 表示采用C标准库提供的random函数。
- 1 表示采用优化增强的random函数。
820.100版本后,新安装集群已默认使用参数1;历史版本及升级上来的集群需要手动修改。
- 点赞
- 收藏
- 关注作者
评论(0)