GaussDB(DWS) analyze使用指南8.1.3及以下版本
一、功能介绍
手动采样:用户在作业中,手动发起的显示analyze。
轮询采样:autovacuum后台线程,轮询发起的analyze。
动态采样:查询时,优化器触发的runtime analyze。
一键最优
autoanalyze = on --开启动态采样
autovacuum = on --开启轮询analyze
autovacuum_analyze_threshold = 50 --设置analyze触发阈值,至少修改50条
autovacuum_analyze_scale_factor = 0.1 --设置analyze触发阈值,至少修改10%
enable_extrapolation_stats = on --开启统计信息推算,防止统计信息收集不及时导致计划差
random_function_version = 1 --使用随机性更好的random函数
功能清单
1. 支持按“database, schema, table, column”四个级别收集统计信息。
2. 支持“手动收集”,“后台轮询采样”和“优化器动态采样”三种方式。
3. 支持“系统级”和“表级”设置“自动触发阈值”和“采样大小。
4. 支持“多列统计信息”。
5. 支持“统计信息导入导出”。
6. 支持“计算模型”可配置,选择样本放内存还是下盘。
7. 支持“采样模型”可配置,不提高采样大小,增强统计信息准确性。
8. 支持“统计信息推理”,统计信息失效时能根据历史统计信息自动推算。
二、手动analyze使用
可参考:https://bbs.huaweicloud.com/blogs/354294
三、轮询analyze使用
后台多个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,再生成最优执行计划。
动态采样触发后统计信息写入系统表,会清理表的修改计数,轮询analyze不再重复触发。
配置方法
autoanalyze = on --开启runtime analyze
约束限制
为控制动态采样对查询的影响,内部做了一些强制限制:
- 采样大小:使用最小的采样大小30000,保证统计信息基本可信。
- 等锁时间:2S无法得到锁则立即放弃analyze,查询继续执行。
- 异常处理:动态采样执行异常会被自动捕获,不影响查询继续执行。
- 并发处理:多个查询触发相同表的动态采样时,第一个人成功触发,其它人跳过不触发。
并发与冲突
动态采样将生成的统计信息存入系统表,需要对目标表加四级锁。会存在一些并发与冲突问题。
- 长事务导致堵塞
我们的锁都是要到事务(包括:显示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会自动超时,自动放弃动态采样。下次查询时再触发。
五、采样大小
默认所有表都采用3000(基于一些理论和实践论证)大小的采样率,确保了大多数情况下统计信息基本可用。
但是一些情况下需要手动调整表的采样大小。
1. 表的数据特征分布不均匀(数据轮询重复,重复倾斜严重等)。
2. 表的数据量比较大,几十亿以上,低采样率难以采准数据特征。
3. 列存为了控制IO,采集部分CU,样本扎堆儿集中在部分CU里。
为了,减轻用户去识别这些问题的难度,我们支持表级修改采样大小。
每张表的数据特征各不相同,所以全局设置可能无法满足各别表的需求。可以通过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%
内存限制
采样越多就会占用更多的内存,我们使用work_mem限制analyze的内存使用,采样大小不得超过该内存限制。
六、多列统计信息
只有使用“基于临时采样表的统计信息计算”的方式才能计算多列统计信息。
default_statistics_target设置为负数时会强制使用基于临时采样表的统计信息计算”。
所以多列统计信息,需要将default_statistics_target设置为负数,推荐-2。
临时表不支持多列统计信息计算。
七、采样模型增强
用最少的样本满足统计信息质量,一直是我们努力的方向。因此我们支持了多种采样模型。
配置方法
cost_model_version = 2
<2:使用默认的蓄水池采样模型
=2:行存使用优化的蓄水池采样模型,列存使用自研的range采样模型
八、统计信息推算
查询匹配数据已经存在,但未在统计信息中时的一个cost估算优化。可在统计信息收集不及时的情况下保证计划不差。
配置方法
enable_extrapolation_stats = on
九、随机函数增强
random_function_version 控制analyze在进行数据采样时选取的random函数版本。
- 0 表示采用C标准库提供的random函数。
- 1 表示采用优化增强的random函数。
新安装集群已默认使用参数1;历史版本及升级上来的集群需要手动修改。
- 点赞
- 收藏
- 关注作者
评论(0)