直方图原理总结:一在oracle中使用直方图来表示数据的分布质量。
它会按照某一列不同值出现的数量的多少,以及出现频率的高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择是使用索引还是全表扫描。
二如果where子句的过滤谓词的列上有一个合理的正确的直方图,它将会对优化器做出正确的选择发挥巨大的作用,使得sql语句执行成本最低从而提升性能。
在获得准确的直方图信息后,基于成本的优化器,就可以决定使用将返回少量行的索引,而避免使用基于限制条件返回许多行的索引。
三直方图的使用不受索引的限制,可以在表的任何列上构建直方图。
构建直方图最主要的原因就是,帮助优化器在表中数据严重倾斜时做出更好的抉择。
例如:一到两个值status=0和status=1,其中=0有100条数据,=1有1000000条数据,只有这两个值就构成了表中的大部分数据数据倾斜,相关查询就可能无法帮助减少满足查询所需的I/O数量如查询status=1。
创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时根据where子句中的值返回表中的80%的记录。
四通常在以下场合建议创建和使用直方图:1当where子句引用了列值的分布情况存在明显偏差的列时:当这中偏差相当明显时,以至于where子句中的值将会使优化器选择不同的执行计划。
这时,应该使用直方图来帮助优化器来修正执行路径。
注意:如果查询不引用该列,则创建直方图没有意义。
这种错误很常见,许多DBA会在偏差列上创建柱状图,即使没有任何查询引用该列2当列值导致不正确的判断时:这种情况通常会发生在多表连接时,例如:假设有个五项的表连接,其结果集只有10行记录。
oracle将会以一种第一个连接的结果集集合基数尽可能小的方式将表连接起来。
通过在中间结果集中携带更少的负载,查询将会运行的更快。
为了使中间结果集最小化,优化器尝试在sql执行的分析阶段评估每个结果集的集合基数。
在偏差的列上拥有直方图将会极大的帮助优化器做出正确的决策。
如优化器对中间结果集的大小做出不正确的判断,它可能会选择一种未达到最优化的表连接方法,因此向该列添加直方图经常会向优化器提供使用最佳连接方法所需的信息。
五直方图的分类:可分为等频直方图和等高直方图等频直方图:针对包含很少不同值的数据集,就是数据分布很均匀。
等高直方图:针对包含很多不同值的数据集。
数据分布不均匀 ,由于列中数据很多,这时数据比较密集,不利于分析和评估,这时直方图需要均衡化默认的,如果一个倾斜列上的唯一值超过了254个,那么oracle会对此列创建等高直方图,否则建立等频直方图。
直方图信息的准确性由两个数值决定,一个是bucket的个数,一个是num_distinct的个数。
一般来说,bucket的数量越多,关于列数据分布的信息就越准确,但统计直方图花费的时间就越多,oracle中bucket的最大为254个,默认是75个。
而sql server中默认是200个。
通常情况下当BUCTET 表的NUM_DISTINCT值的时候得到的是FREQUENCY频率直方图。
由于满足BUCTET = 表的NUM_DISTINCT值概率较低,所以在Oracle中生成的直方图大部分是HEIGHT BALANCED高度平衡直方图。
在Oracle 10GR2之前如果使用dbms_stats包来创建直方图,那么如果指定需要创建的直方图的桶的数目与表的NUM_DISTINCT值相等,那么几乎无法创建出一个FREQUENCY频率直方图,此时为了得到频率直方图只能使用analyze命令的“for all columns size 表的NUM_DISTINCT值”,这在某种程度上来说是一个退步,但这个问题在Oracle 10GR2后被修正。
但是如果列中有180 - 200个不同值时,还是无法创建FREQUENCY频率直方图.此时需要手工建立直方图,并写入数据字典方能完成FREQUENCY频率直方图的创建。
对于含有较少的不同值而且数据分布又非常不均匀的数据集来说,创建FREQUENCY频率直方图将会更加合适,因为它不存在会将低频出现的记录存入高频桶中的情况,而HEIGHT BALANCED高度平衡直方图在存储桶bucket数分配不合理时就可能会出现这种情况。
因此一定要在创建直方图前确定使用何种直方图,并且要合理估计存储桶bucket个数。
六如何创建直方图:通过使用早先的analyze命令和最新的dbms_stats工具包都可以创建直方图。
Oracle推荐使用后者来创建直方图,而且直方图的创建不受任何条件限制,可以在一张表上的任何你想创建直方图的列上创建直方图。
我们这里主要介绍如何通过dbms_stats包来创建直方图。
Oracle 通过指定 dbms_stats 的 method_opt 参数,来创建直方图。
在 method_opt 子句中有三个相关选项,即 skewonly、repeat 和 auto。
“skewonly” 选项,它的时间性很强,因为它检查每个索引中每列值的分布。
如果 dbms_stats 发现一个索引中具有不均匀分布的列,它将为该索引创建直方图,以帮助基于成本的 SQL优化器决定是使用索引还是全表扫描...