#统计信息
YashanDB提供统计信息功能,主要用于收集表、索引、列的相关信息。
# 收集内容
表统计信息
包括分区表、临时表(全局)等所有表对象的基础信息,例如:
- row count: 表的row数量
- block count:表的data block数量
- empty block count:block的rows为0时为empty block
- chaint count:行链接/迁移的数量
- average space:block的平均空闲空间,即block的free size
- average row size:平均row size
- sample size:抽样的row数量
- last analyzed time:统计信息收集时间,每次收集之后更新
索引统计信息
索引的基础信息,例如:
- row count:索引的row数量
- leaf block count:叶子block的数量
- first key distinct count:组合索引第一个col的distinct数量,用于skip scan
- all key distinct count:distinct key的数量
- average leaf blocks per key:每个key对应的leaf block数量,唯一索引为1
- average data blocks per key:每个key对应的data block数量
- btree level:BTree的level
- cluster factor:索引的聚集因子,反映key对应的data block的分布情况,row越有序,factor越小,scan的代价越小
- last analyzed time:统计信息收集时间,每次收集之后更新
列统计信息
包括列的基础信息和列的直方图,例如:
- distinct:列value的唯一值的数量
- null count:列values为null的数量
- low/high value:列的最大最小值
- average column length:列的平均长度
- maximum column length:列的最大长度
- last analyzed time:统计信息收集时间,每次收集之后更新
- density:密度,用于无直方图情况下优化器估计选择率
- number of buckets:直方图桶的个数
- sample size:抽样的row数量
- 频率直方图:通过endpoint number和endpoint value来表示,两个值满足以下要求:
- endpoint number:小于等于当前bucket value的累计值。
- endpoint value:当前bucket中的存放的value。
- 等高直方图:通过endpoint number和endpoint value来表示,假设bucket的数量为m(0号bucket不计算在内),两个值满足以下要求:
- endpoint number:等于bucket number。0号bucket存放的是最小值,其余bucket编号为1~m,用于存放剩余的值。
- endpoint value:当前bucket中的存放的所有value的最大值。
- TopN直方图:与频率直方图相似,只是只记录前bucket数量的distinct。按distinct排序,前bucket数量distinct的个数至少要占rows的(1 - 1/n) * 100%。
- endpoint number:小于等于当前bucket value的累计值。
- endpoint value:当前bucket中的存放的value。
- 混合直方图:混合直方图是频率直方图和等高直方图的结合,其中endpoint value不会跨多个桶,并且记录endpoint value的个数。
- endpoint number:小于等于当前bucket value的累计值。
- endpoint value:桶中的最大值。
- repeat cnt:endpoint value出现个数。
# 收集方式
动态收集
优化器在执行计划生成阶段发现统计信息缺失或无效(missing/stale/insufficient)时,将触发动态收集动作。
通过OPTIMIZER_DYNAMIC_SAMPLING参数可以设置动态收集的级别,每种级别定义了动态收集触发的条件以及采样率。
手动收集
单机部署/共享集群部署中使用DBMS_STATS高级包,分布式部署中使用DBMS_STATS高级包或ANALYZE TABLE语句,让用户对统计信息进行管理和手动触发指定的收集动作。
自动收集
YashanDB内置了定时任务GATHER_STATS_JOB,默认每日凌晨2:00
开始收集全库的统计信息,包括统计信息缺失或统计信息已经失效的对象的收集。用户可以通过DBMS_SCHEDULER高级包维护该统计信息定时任务。
自动收集统计信息不适用于分布式部署。
通过yasboot进行自动收集
yasboot工具实现了定时收集的功能,单机部署/分布式部署可以借助job命令来实现自动收集的功能。
# 收集精准化
# 统计信息自动失效
YashanDB通过统计信息自动失效机制,在表的数据发生大的变化(变化率超过指定阈值),以及表发生一些DDL变化(truncate table/partition、drop partition、add hash partition)时,将该表上已收集的统计信息置为失效。
数据变化监控
当STATISTICS_LEVEL参数配置为typical或all时,系统会一直监控表的数据变化,包括表上的DML、truncate表/分区等,通过DBA_TAB_MODIFICATIONS、USER_TAB_MODIFICATIONS和ALL_TAB_MODIFICATIONS视图可以查看这些变化。
数据变化持久化
为保证性能,变化监控在内存中进行,DDL变化实时存盘,DML变化通过后台任务定时(15分钟)将变化数据存盘,数据库Shutdown前也会执行变化数据的持久化。本操作通过DBMS_STATS高级包的FLUSH_DATABASE_MONITORING_INFO程序实现,该程序支持用户手动调用执行。
重新收集
通过系统内置job定时重新收集统计信息(全库),或在需要时手动触发收集,可选择收集指定对象的信息或全库信息(在线的全库收集可能会消耗较多的系统资源,运行较长时间)。
重新收集统计信息后,其状态被恢复为未失效,优化器将可以获得真实的统计信息,生成可信的执行计划。
数据变化重置
在以下时间点,上述监控生成的数据变化信息被清空重置:
- 统计信息收集后
- 表或分区被删除
# 统计信息锁定与解锁
大多数情况下,用户均使用自动任务进行批量的统计信息收集,此时可能存在的一个问题就是,有些如日志类的大表对于调优没有什么价值且很耗时,因此并不希望被一直收集。同时,还可能存在某些表,用户希望在某一时期锁定自己认为最优的统计信息状态,以生成期望的执行计划,并在另一时期解锁让其更新统计信息。为解决这些问题,YashanDB提供统计信息锁定/解锁功能。
通过DBMS_STATS高级包的LOCK/UNLOCK相关存储过程可以实现按用户、表、表分区级别的统计信息锁定/解锁。指定的统计信息被锁定后,所有的统计信息收集相关动作(gather/set/delete等)对其不再生效。
# 收集结果
用户可以通过下列视图查看统计信息收集的结果数据:
视图名称 | 说明 |
---|---|
DBA_TAB_STATISTICS | 包含已收集的所有表的统计信息 |
DBA_IND_STATISTICS | 包含已收集的所有索引的统计信息 |
DBA_TAB_COL_STATISTICS | 包含已收集的所有列的统计信息 |
DBA_HISTOGRAMS | 包含已收集的所有列的直方图 |
DBA_PART_COL_STATISTICS | 包含已收集的所有分区列的统计信息 |
DBA_PART_HISTOGRAMS | 包含已收集的所有分区列的直方图 |