ITPub博客

首页 > 数据库 > Oracle > 直方图学习

直方图学习

Oracle 作者:studywell 时间:2018-04-25 22:08:08 0 删除 编辑
参考文档:
https://blog.csdn.net/javacoffe/article/details/5578206
https://blog.csdn.net/tchic/article/details/52434006
http://www.cnblogs.com/polestar/p/4330968.html
http://www.xifenfei.com/2011/09/oracle%E7%9B%B4%E6%96%B9%E5%9B%BE%E7%90%86%E8%A7%A3%E4%B8%8E%E5%AE%9E%E9%AA%8C.html
   
     
直方图学习


一.何为直方图
  直方图是一种几何形图表,它是根据从生产过程中收集来的质量数据分布情况,画成以组距为底边、以频数为高度的一系列连接起来的直方型矩形图,如图所示


二.ORACLE 直方图
  在Oracle中直方图是一种对数据分布情况进行描述的工具。它会按照某一列不同值出现数量多少,以及出现的频率高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择。在某些情况下,表的列中的数值分布将会影响优化器使用索引还是执行全表扫描的决策。


  直方图的使用不受索引的限制,可以在表的任何列上构建直方图。构造直方图最主要的原因就是帮助优化器在表中数据严重偏斜时做出更好的规划。如:一到两个值(status=0和status=1,其中=0有100条数据,=1有1000000条数据,只有这两个值)就构成了表中的大部分数据(数据倾斜),相关查询就可能无法帮助减少满足查询所需的I/O数量(如查询status=1)。创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时根据where子句中的值返回表中的80%的记录。


三.直方图分类及原理
等频直方图:针对包含很少不同值的数据集,就是数据分布很均匀。
等高直方图:针对包含很多不同值的数据集,数据分布不均匀。


  直方图信息的准确性由两个数值决定,一个是bucket的个数,一个是num_distinct的个数。一般来说,bucket的数量越多,关于列数据分布的信息就越准确,但统计直方图花费的时间就越多,oracle中bucket的最大为254个,默认是75个。而sql server中默认是200个。


当BUCTET < 表的NUM_DISTINCT值得到的是HEIGHT BALANCED 等高直方图
当BUCTET > 表的NUM_DISTINCT值的时候得到的是FREQUENCY 等频直方图
  由于满足BUCTET = 表的NUM_DISTINCT值概率较低,所以在Oracle中生成的直方图大部分是HEIGHT BALANCED(高度平衡)直方图。




四.Oracle中使用直方图的场合
在分析表或索引时,直方图用于记录数据的分布。通过获得该信息,基于成本的优 化器就可以决定使用将返回少量行的索引,而避免使用基于限制条件返回许多行的索引。直方图的使用不受索引的限制,可以在表的任何列上构建直方图。
构造直方图最主要的原因就是帮助优化器在表中数据严重偏斜时做出更好的规划:例如,如果一到两个值构成了表中的大部分数据(数据偏斜),相关的索引就可能无法帮助减少满足查询所需的I/O数量。创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时应该根据WHERE子句中的值返回表中80%的记录。
通常情况下在以下场合中建议使用直方图:
(1)、当Where子句引用了列值分布存在明显偏差的列时:当这种偏差相当明显时,以至于 WHERE 子句中的值将会使优化器选择不同的执行计划。这时应该使用直方图来帮助优化器来修正执行路径。(注意:如果查询不引用该列,则创建直方图没有意义。这种错误很常见,许多 DBA 会在偏差列上创建柱状图,即使没有任何查询引用该列。)


(2)、当列值导致不正确的判断时:这种情况通常会发生在多表连接时,例如,假设我们有一个五项的表联接,其结果集只有 10 行。Oracle 将会以一种使第一个联接的结果集(集合基数)尽可能小的方式将表联接起来。通过在中间结果集中携带更少的负载,查询将会运行得更快。为了使中间结果最小化,优化器尝试在 SQL 执行的分析阶段评估每个结果集的集合基数。在偏差的列上拥有直方图将会极大地帮助优化器作出正确的决策。如优化器对中间结果集的大小作出不正确的判断,它可能会选择一种未达到最优化的表联接方法。因此向该列添加直方图经常会向优化器提供使用最佳联接方法所需的信息


五.创建直方图
Oracle 通过指定 dbms_stats. gather_table_stats 的 method_opt 参数,来创建直方图的。 method_opt参数说明


==========================================================================================================
Accepts either of the following options, or both in combination:


FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause]
FOR COLUMNS [size clause] column [size_clause] [,column [size_clause]...]
size_clause is defined as size_clause := SIZE {integer | REPEAT | AUTO | SKEWONLY}


column is defined as column := column_name | extension name | extension


- integer : Number of histogram buckets. Must be in the range [1,254].
- REPEAT : Collects histograms only on the columns that already have histograms


- AUTO : Oracle determines the columns on which to collect histograms based on data distribution and the workload of the columns.
- SKEWONLY : Oracle determines the columns on which to collect histograms based on the data distribution of the columns.
- column_name : Name of a column
- extension : can be either a column group in the format of (column_name, Colume_name [, ...]) or an expression


The default is FOR ALL COLUMNS SIZE AUTO.
==========================================================================================================


Examples
An extension can be either a column group (see Example 1) or an expression (see Example 2).


Example 1  数据库自动收集
DBMS_STATS.GATHER_TABLE_STATS('SH', 'SALES', method_opt => 'FOR COLUMNS (empno, deptno)'); 
DBMS_stats.gather_table_stats(cascade => TRUE,degree => 2,estimate_percent => 100,force => TRUE,ownname => USER,tabname => 'T_XFF');
--在gather_table_stats方法中,默认的method_opt值为:FOR ALL COLUMNS SIZE AUTO,所以也是会收集直方图的统计信息(和oracle版本相关)
    
Example 2
DBMS_STATS.GATHER_TABLE_STATS('SH', 'SALES', method_opt => 'FOR COLUMNS (sal+comm)');


Example 3
DBMS_STATS.GATHER_TABLE_STATS('SH', 'SALES', method_opt => 'FOR COLUMNS sal size 1');
注:1表示1个bucket的数量,即不做直方图处理,禁止产生直方图(size 1)


Example 4
DBMS_STATS.GATHER_TABLE_STATS('SH', 'SALES', method_opt => 'FOR COLUMNS (sal+comm) size 10');
注:把sal,comm两列,按(sal+comm)表达式的和分成10个bucket。


Example 5
DBMS_STATS.GATHER_TABLE_STATS('SH', 'SALES', method_opt => 'FOR COLUMNS (sal,comm) size 10');


Example 6










--查看直方图信息
SQL> col COLUMN_NAME format a20
SQL> col TABLE_NAME format a15
SQL> SELECT * FROM user_histograms WHERE table_name='T_XFF' AND column_name='OBJECT_ID';
TABLE COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_A
----- ---------- --------------- -------------- ----------
T_XFF OBJECT_ID            1          2
T_XFF OBJECT_ID            2          3
……
T_XFF OBJECT_ID            73205          76789
T_XFF OBJECT_ID            73206          76800


--查看直方图类型 
SQL>   SELECT COLUMN_NAME,HISTOGRAM FROM USER_TAB_COLS WHERE TABLE_NAME='T_XFF' AND column_name='OBJECT_ID';
  
COLUMN_NAME                    HISTOGRAM
------------------------------ ---------------
OBJECT_ID                      FREQUENCY




--注:ENDPOINT_NUMBER列值是bucket(桶)的标识号。如只有0、1两个bucket说明没有产生直方图信息。
--等频直方图,EDNPOINT_NUMBER是累计值,EDNPOINT_NUMBER(N)-EDNPOINT_NUMBER(N-1)=当前桶的数据个数,EDNPOINT_VALUE是列的值。它为每一个列值分配了一个桶。


--在等高直方图中,EDNPOINT_NUMBER代表桶号,这一点与等频直方图不同。


--等频直方图比等高直方图稳定、精确。
--列的唯一值是超过254的。只能使用等高直方图了。
--在没有直方图的情况下,在B列上进行等值查询的时候,都是索引范围扫描(即使返回总数据量的80%)
---查看执行计划
SQL> set autot trace exp stat
SQL> select object_name from t_xff where object_id=100;

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29519108/viewspace-2153361/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: ORACLE日期类型
请登录后发表评论 登录
全部评论

注册时间:2014-03-04

  • 博文量
    307
  • 访问量
    535421