ORACLE直方图(10g)
为什么需要直方图 ?当表中一列数据比较的值分布比较均匀时,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)的更多相关文章
- Oracle直方图的详细解析
yuanwen:http://blog.csdn.net/javacoffe/article/details/5578206 Oracle直方图解析 一. 何谓直方图: 直方图是一种统计学上的工 ...
- Oracle直方图的详细解析(转)
Oracle直方图解析 一. 何谓直方图: 直方图是一种统计学上的工具,并非Oracle专有.通常用于对被管理对象的某个方面的质量情况进行管理,通常情况下它会表现为一种几何图形表,这个图形表是根 ...
- 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 ...
- 问题: Oracle Database 10g 未在当前操作系统中经过认证
问题: Oracle Database 10g 未在当前操作系统中经过认证 在Windows 7中安装Oracle 10g. 使用的Orcale版本是10g. 步骤1: 在Orcale官网上下载,下载 ...
- Creating Custom Login Screen In Oracle Forms 10g
Below is the example plsql unit to validate login credentials and after successful validation open a ...
- 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: ...
- 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 ...
- 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 ...
- Oracle 直方图理论
一.何为直方图 直方图是一种几何形图表,它是根据从生产过程中收集来的质量数据分布情况,画成以组距为底边.以频数为高度的一系列连接起来的直方型矩形图,如图所示 二.ORACLE 直方图 在Oracle中 ...
- Linux 上Oracle RAC 10g 升级到 Oracle RAC 11g
了解如何在 Oracle Enterprise Linux 5 上逐步将 Oracle RAC 10g 第 2 版升级到 Oracle RAC 11g. Oracle 数据库 11g(即,新一代网格计 ...
随机推荐
- iphone怎么投屏到电脑屏幕上
随着苹果手机的更显换代,苹果手机的功能越来越强大,其中iphone手机更新了airplay镜像功能,所以想要手机投屏电脑的小伙伴就更加方便了,但是iphone怎么投屏到电脑呢?大家不用着急,下面即将为 ...
- Python入门基础之条件判断、循环、dict和set
Python之if语句 比如,输入用户年龄,根据年龄打印不同的内容,在Python程序中,可以用if语句实现: age = 20 if age >= 18: print 'your age is ...
- Android Studio 之 注释模板
我们看有的项目的文档,会发现它的注释写的很好看,很规范. 而如果你的代码注释还是在用简单的 // 或者 /**/ ,那就学习一下在Android Studio中如何进行注释模板的设置 首先看下面代码 ...
- Android为TV端助力 bitmap和数据流的互转
Bitmap aa = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); InputStream input ...
- "BLAME" is out.
The latest feature animation film "BLAME" is watchable on the Netflix. Rendering was done ...
- mongodb数据分组按字符串split
db.getCollection('users').aggregate([ {$match:{ZWBH:11}}, {$unwind:'$UUID'}, {$project : { PM : { $s ...
- 2015年6月6日,杨学明老师《IT技术人才管理角色转型与实践》专题培训在苏宁云商成功举办!
2015.6.6,在中国南京苏宁总部,研发资深顾问.资深讲师为苏宁易购IT事业部全体产品总监.研发总监进行了为期一天的<IT技术人才管理角色转型与实践>的内训服务. 杨学明老师分别从技术人 ...
- Linux 中如何避免 rm -rf /*
Linux 的删除命令中 rm中没有回收站的概念,一旦文件被删除比较难还原.更可怕的是rm -rf /*,连自己都能删 这命令太危险了,弄错了就核爆了,带来的损失的巨大的.比如 Gitlab.com ...
- JAVA项目从运维部署到项目开发(二.ZooKeeper)
一.zookeeper的相关介绍 点击查看 二.下载.安装与配置 1.ZooKeeper官网下载地址(点击跳转),当前稳定版本为V3.4.12.Liniux下可以在指定目录,使用wget命令下载. h ...
- 如何在 Flickr 上找到又酷,又有趣,且版权自由的照片?
[编者按]本文作者为 Alex Walker,主要介绍在 Flickr 上进行照片搜索时的一些技巧.本文系国内 ITOM 管理平台 OneAPM 编译呈现. 我们一直都在寻找新奇的,与众不同的设计.图 ...