为什么需要直方图 ?当表中一列数据比较的值分布比较均匀时,optimzer可以很好的通过最大值,最小值和NDV(唯一值的个数),就可以判断出cardinality.对于cardinality越精确,optimzer就可以更加好的选择执行计划。

--创建测试表并插入数据

create table t1(a int,b varchar2(100));

begin

for i in 1..100 loop

insert into t1 values (1,'abcd');

end loop;

commit;

end;

/

begin

for i in 1..100 loop

insert into t1 values (2,'efg');

end loop;

commit;

end;

/

---收集统计信息

exec dbms_stats.gather_table_stats(tabname => 't1',ownname => user,method_opt => 'for all columns size 1'); --for all columns size 1 不收集直方图信息

---执行一个语句来看看optimizer评估的行

explain plan for select * from t1 where a=1;

select * from table(dbms_xplan.display());

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |   100 |   700 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T2   |   100 |   700 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

返回100行,说明优化器在这种数据平均分布的情况下评估很准确。现在insert into t1 values(3,'mnb'); 一行,人为的模拟数据分布不均,再次收集统计信息

explain plan for select * from t1 where a=3;

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 1513984157

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |    67 |   469 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T2   |    67 |   469 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

优化器评估为67行.计算公式为 rows/ndv=(200/3)=66.66666

看看收集了集方图后的结果

SQL> exec dbms_stats.gather_table_stats(tabname => 'T1',ownname => user,method_opt => 'FOR ALL COLUMNS SIZE AUTO');

SQL>  explain plan for select * from t1 where a=3;

PLAN_TABLE_OUTPUT

--------------------------------------------------------------------------------

Plan hash value: 1513984157

--------------------------------------------------------------------------

| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |

--------------------------------------------------------------------------

|   0 | SELECT STATEMENT  |      |     1 |     7 |     3   (0)| 00:00:01 |

|*  1 |  TABLE ACCESS FULL| T2   |     1 |     7 |     3   (0)| 00:00:01 |

--------------------------------------------------------------------------

可以看出通过增加了直方图,oracle比较准确的评估了cardinality。

SQL> select column_name,histogram from user_tab_col_statistics where table_name='T2';

COLUMN_NAME                    HISTOGRAM

------------------------------ ---------------

A                              FREQUENCY       --频率直方图

B                              NONE

直方图分为两种频率直方图和高度平衡直方图

直方图的限制:1,收集直方图有开销,如cpu和磁盘空间;2,对于每个栏位超过254的distinct value,频率直方图的作用开始下降

随着NDV的增加,精度进一步下降,这时候只能使用高度平衡直方图.3,对于字符类型,只能收集前32个字节;

4,在非索引的栏位上收集直方图的效果有限.

高度平衡和频率直方图的选择:对于某个栏位的NDV小于所定义的桶数,使用频率直方图,否则使用高度平衡直方图。两种方式的最大的桶数为254,

SQL> create table t2(a int);

begin

for i in 1..76 loop

insert into t2 values (i);

end loop;

commit;

end;

/

SQL> select count(distinct a) from t2;  --insert 76种不同的值

COUNT(DISTINCTA)

----------------

76

SQL> exec dbms_stats.gather_table_stats(tabname => 'T2',ownname => user,method_opt => 'FOR COLUMNS A SIZE 75');

人为的定义桶数小于NDV,在这种条件,oracle会使用高度平衡直方图,因为频率直方图75个bucket容不下76

SQL>  select column_name,histogram from user_tab_col_statistics where table_name='T2';

COLUMN_NAME                    HISTOGRAM

------------------------------ ---------------

A                              HEIGHT BALANCED

对于频率直方图,如果NDV小于254的情况,ndv应该是和桶数相等的.有些bug会产生不一致,导致评估不准确,具体可以参考metalink的相关bug。

SQL> select count(b.endpoint_value) from user_histograms b where table_name='T1' and column_name='A';

COUNT(B.ENDPOINT_VALUE)

-----------------------

3

SQL> select table_name,column_name,num_distinct from user_tab_col_statistics where table_name='T1' and column_name='A';

TABLE_NAME                     COLUMN_NAME                    NUM_DISTINCT

------------------------------ ------------------------------ ------------

T2                             A                                         3

一般建议的收集方法为'FOR ALL COLUMNS SIZE AUTO',除非有很好的理由去更改,由oracle自行决定是否需要histogram和桶数

为什么需要直方图 ?当表中一列数据比较的值分布比较均匀时,optimzer可以很好的通过最大值,最小值和NDV(唯一值的个数),就可以判断出cardinality.对于cardinality越精确,optimzer就可以更加好的选择执行计划。
--创建测试表并插入数据create table t1(a int,b varchar2(100));beginfor i in 1..100 loopinsert into t1 values (1,'abcd');end loop;commit;end;/beginfor i in 1..100 loopinsert into t1 values (2,'efg');end loop;commit;end;/---收集统计信息exec dbms_stats.gather_table_stats(tabname => 't1',ownname => user,method_opt => 'for all columns size 1'); --for all columns size 1 不收集直方图信息
---执行一个语句来看看optimizer评估的行explain plan for select * from t1 where a=1;select * from table(dbms_xplan.display());--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |   100 |   700 |     3   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| T2   |   100 |   700 |     3   (0)| 00:00:01 |--------------------------------------------------------------------------返回100行,说明优化器在这种数据平均分布的情况下评估很准确。现在insert into t1 values(3,'mnb'); 一行,人为的模拟数据分布不均,再次收集统计信息explain plan for select * from t1 where a=3;PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------Plan hash value: 1513984157--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |    67 |   469 |     3   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| T2   |    67 |   469 |     3   (0)| 00:00:01 |--------------------------------------------------------------------------优化器评估为67行.计算公式为 rows/ndv=(200/3)=66.66666看看收集了集方图后的结果SQL> exec dbms_stats.gather_table_stats(tabname => 'T1',ownname => user,method_opt => 'FOR ALL COLUMNS SIZE AUTO');SQL>  explain plan for select * from t1 where a=3;PLAN_TABLE_OUTPUT--------------------------------------------------------------------------------Plan hash value: 1513984157--------------------------------------------------------------------------| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |--------------------------------------------------------------------------|   0 | SELECT STATEMENT  |      |     1 |     7 |     3   (0)| 00:00:01 ||*  1 |  TABLE ACCESS FULL| T2   |     1 |     7 |     3   (0)| 00:00:01 |--------------------------------------------------------------------------可以看出通过增加了直方图,oracle比较准确的评估了cardinality。SQL> select column_name,histogram from user_tab_col_statistics where table_name='T2';COLUMN_NAME                    HISTOGRAM------------------------------ ---------------A                              FREQUENCY       --频率直方图B                              NONE直方图分为两种频率直方图和高度平衡直方图直方图的限制:1,收集直方图有开销,如cpu和磁盘空间;2,对于每个栏位超过254的distinct value,频率直方图的作用开始下降随着NDV的增加,精度进一步下降,这时候只能使用高度平衡直方图.3,对于字符类型,只能收集前32个字节;4,在非索引的栏位上收集直方图的效果有限.高度平衡和频率直方图的选择:对于某个栏位的NDV小于所定义的桶数,使用频率直方图,否则使用高度平衡直方图。两种方式的最大的桶数为254,SQL> create table t2(a int);beginfor i in 1..76 loopinsert into t2 values (i);end loop;commit;end;/SQL> select count(distinct a) from t2;  --insert 76种不同的值COUNT(DISTINCTA)----------------              76SQL> exec dbms_stats.gather_table_stats(tabname => 'T2',ownname => user,method_opt => 'FOR COLUMNS A SIZE 75');人为的定义桶数小于NDV,在这种条件,oracle会使用高度平衡直方图,因为频率直方图75个bucket容不下76SQL>  select column_name,histogram from user_tab_col_statistics where table_name='T2';COLUMN_NAME                    HISTOGRAM------------------------------ ---------------A                              HEIGHT BALANCED
对于频率直方图,如果NDV小于254的情况,ndv应该是和桶数相等的.有些bug会产生不一致,导致评估不准确,具体可以参考metalink的相关bug。SQL> select count(b.endpoint_value) from user_histograms b where table_name='T1' and column_name='A';COUNT(B.ENDPOINT_VALUE)-----------------------                      3SQL> select table_name,column_name,num_distinct from user_tab_col_statistics where table_name='T1' and column_name='A';TABLE_NAME                     COLUMN_NAME                    NUM_DISTINCT------------------------------ ------------------------------ ------------T2                             A                                         3一般建议的收集方法为'FOR ALL COLUMNS SIZE AUTO',除非有很好的理由去更改,由oracle自行决定是否需要histogram和桶数

ORACLE直方图(10g)的更多相关文章

  1. Oracle直方图的详细解析

    yuanwen:http://blog.csdn.net/javacoffe/article/details/5578206 Oracle直方图解析 一.    何谓直方图: 直方图是一种统计学上的工 ...

  2. Oracle直方图的详细解析(转)

    Oracle直方图解析 一.    何谓直方图: 直方图是一种统计学上的工具,并非Oracle专有.通常用于对被管理对象的某个方面的质量情况进行管理,通常情况下它会表现为一种几何图形表,这个图形表是根 ...

  3. Oracle Forms 10g Tutorial Ebook Download - Oracle Forms Blog

    A step by step tutorial for Oracle Forms 10g development. This guide is helpful for freshers in Orac ...

  4. 问题: Oracle Database 10g 未在当前操作系统中经过认证

    问题: Oracle Database 10g 未在当前操作系统中经过认证 在Windows 7中安装Oracle 10g. 使用的Orcale版本是10g. 步骤1: 在Orcale官网上下载,下载 ...

  5. Creating Custom Login Screen In Oracle Forms 10g

    Below is the example plsql unit to validate login credentials and after successful validation open a ...

  6. Writing Text Files On The Client in Oracle Forms 10g

    Below is the example to write file on client in Oracle Forms 10g with webutil library package.Note:  ...

  7. Horizontal Toolbar With Navigational Buttons Form Sample For Oracle Forms 10g/11g

    Sharing an Oracle Form Htoolbar.fmb for Oracle Forms 10g/11g containing Horizontal Toolbar canvas an ...

  8. Calling / Running a report in Oracle forms 10g / 11g

    Calling / Running a report in Oracle forms 10g / 11g Below is the procedure to call a report in Orac ...

  9. Oracle 直方图理论

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

  10. Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g

    了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级到 Oracle RAC 11g. Oracle 数据库 11g(即,新一代网格计 ...

随机推荐

  1. vuejs 1.x - 实例:搜索过滤

    <!DOCTYPE html> <html> <head> <meta name="viewport" content="wid ...

  2. JMeter 中实现发送Java请求

    JMeter 中实现发送Java请求 1.  步骤1 新建JAVA项目 File -> New -> Java Project 如上图,填写Project Name,然后Next,打开以J ...

  3. Android--底部导航栏的动态替换方案

    1.通常来说,一般情况下,我们的app的BottomTab会有集中实现方式. 自定义view,然后自己写逻辑去实现互斥. 自由度最高,因为啥都是自己写的. 使用RadioGroup+RadioButt ...

  4. .NET Core 2.0

    下载 Visual Studio 2017 version 15.3 下载 .NET Core 2.0 下载 Visual Studio for Mac 微软今天发布了.NET Core 2.0 版本 ...

  5. 腾讯云Centos安装gitlab

    参考了网上很多人写的安装教程,结果并不好,最后阅读了官方的英文api,才安装成功,这里记录下来,方便以后使用.我的安装环境为腾讯云主机Centos7.3 64bit gitlab官方api地址点我试试 ...

  6. 一张图教你读懂AI简史

  7. jQuery ajax()使用serialize()提交form数据到后台

    1.选中要删除的学生信息 2.点击 删除选中 按钮,把复选框中的值取出提交到后台 3.后台获取选中的id 4.前端也跟着删除数据 示例代码: 前端代码: <!DOCTYPE html> & ...

  8. Java集合:List、Set和Map的区别,ArrayList和LinkedList有何区别..........

    一.数组和集合的区别: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型): 集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! J ...

  9. c/c++ 哈希表 hashtable

    c/c++ 哈希表 hashtable 概念:用key去查找value 实现hash函数有很多方法,本文用除留余数法. 除留余数法的概念: 取一个固定的基数的余数,注意不能用偶数,用偶数的话,分布会不 ...

  10. Linux:固定 ip

    默认情况下,安装完操作系统时,ip是采用dhcp来动态分配的.通常我们需要将其固定下来. 不然 每次系统重启后,ip都会变动,这样会给日常工作带来不必要的麻烦的. 下面就是在rhel .centos  ...