Oracle数据库统计信息与直方图

Oracle 10g及以后的版本均采用CBO,而取消了之前的RBO。在CBO中数据库会对数据表的统计信息进行收集,并且基于收集的结果进行执行计划的选择。执行计划中的Cost的计算方式默认为CPU+I/O两者之和。 所以一般我们看执行计划时,Cost越低,SQL的性能就越好。

下面主要介绍统计信息收集的内容1 2

1.表的统计信息

包含表行数,使用的块数,空的块数,块的使用率,行迁移和链接的数量,pctfree,pctused的数据,行的平均大小:

SELECT 
	NUM_ROWS, --表中的记录数
	BLOCKS, --表中数据所占的数据块数
	EMPTY_BLOCKS, --表中的空块数
	AVG_SPACE, --数据块中平均的使用空间
	CHAIN_CNT, --表中行连接和行迁移的数量
	AVG_ROW_LEN --每条记录的平均长度
FROM USER_TABLES;

2.索引列的统计信息

包含索引的深度(B-Tree的级别),索引叶级的块数量,集群因子(clustering_factor), 唯一值的个数。

SELECT 
	BLEVEL, --索引的层数
	LEAF_BLOCKS, --叶子结点的个数
	DISTINCT_KEYS, --唯一值的个数
	AVG_LEAF_BLOCKS_PER_KEY, --每个KEY的平均叶块个数
	AVG_DATA_BLOCKS_PER_KEY, --每个KEY的平均数据块个数
	CLUSTERING_FACTOR --群集因子
FROM USER_INDEXES;

clustering factor反映的是数据块顺序程度和索引叶子节点的相合程度。索引叶子节点是有序的,clustering factor反映了索引对应的数据行在数据块里面的离散程度,即相同或者相邻的索引值行是不是在相同的数据块上。可见通过通过索引重建无法改变这个因子。这个因子主要影响index range scan和对于 index equal的查询影响相对小些。

3.列的统计信息

包含唯一的值个数,列最大小值,密度(选择率),数据分布(直方图信息),NULL值个数

SELECT
	NUM_DISTINCT, --唯一值的个数
	LOW_VALUE, --列上的最小值
	HIGH_VALUE, --列上的最大值
	DENSITY, --选择率因子(密度)
	NUM_NULLS, --空值的个数
	NUM_BUCKETS, --直方图的BUCKET个数
	HISTOGRAM --直方图的类型
FROM USER_TAB_COLUMNS;

4.直方图

直方图就是用来分析数据在列上的分布。直方图参数有如下几个:统计比例(采样率,一般为20%),要统计的列,直方图bucket的个数(为1相当于不统计直方图),并发度。

直方图可以反映列值的分布,在oracle中分为两种:1.频率直方图(针对列的NUM_DISTINCT较少时使用)。2.高度平衡直方图(针对NUM_DISTINCT大于BUCKET的情况)。oracle支持的BUCKET最大为254。

oracle在做统计更新时会根据直方图的统计信息来进行COST值的计算进而影响执行计划的选择,一般建议在当Where子句引用了列值分布存在明显偏差的列时,导致oracle执行计划选择错误时使用(这种情况也可以采用hint的方式来优化)。更多直方图的信息见3。实际上由于对于表很大时才会遇到执行计划选择问题,但是由于统计信息采样率一般很低(生产甚至是5%,这也是因为统计信息搜集也很消耗资源和时间),这种情况下采用直方图效果不好,一般不采用。

参考资料:

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《ITechLib》

留言:

(lesstile enabled - surround code blocks with ---)