一.何谓直方图:
直方图是一种统计学上的工具,并非Oracle专有。通常用于对被管理对象的某个方面的质量情况进行管理,通常情况下它会表现为一种几何图形表,这个图形表是根据从实际环境中所收集来的被管理对象某个方面的质量分布情况的数据所绘制成的,通常会画成以数量为底边,以频度为高度的一系列连接起来的矩形图,因此直方图在统计学上也称为质量分布图。比如下图所示,是一个以关学生化学考试成绩分数分布情况绘制的直方图:
二.Oracle中直方图的作用:
既然直方图是一种对被管理对象某一方面质量进行管理的描述工具,那么在Oracle中自然它也是对Oracle中某个对象质量的描述工具,这个对象就是Oracle中最重要的东西——“数据”。
在Oracle中直方图是一种对数据分布质量情况进行描述的工具。它会按照某一列不同值出现数量多少,以及出现的频率高低来绘制数据的分布情况,以便能够指导优化器根据数据的分布做出正确的选择。在某些情况下,表的列中的数值分布将会影响优化器使用索引还是执行全表扫描的决策。当 where 子句的值具有不成比例数量的数值时,将出现这种情况,使得全表扫描比索引访问的成本更低。这种情况下如果where 子句的过滤谓词列之上上有一个合理的正确的直方图,将会对优化器做出正确的选择发挥巨大的作用,使得SQL语句执行成本最低从而提升性能。
三.Oracle中使用直方图的场合:
在分析表或索引时,直方图用于记录数据的分布。通过获得该信息,基于成本的优 化器就可以决定使用将返回少量行的索引,而避免使用基于限制条件返回许多行的索引。直方图的使用不受索引的限制,可以在表的任何列上构建直方图。
构造直方图最主要的原因就是帮助优化器在表中数据严重偏斜时做出更好的规划:例如,如果一到两个值构成了表中的大部分数据(数据偏斜),相关的索引就可能无法帮助减少满足查询所需的I/O数量。创建直方图可以让基于成本的优化器知道何时使用索引才最合适,或何时应该根据WHERE子句中的值返回表中80%的记录。
通常情况下在以下场合中建议使用直方图:
(1)、当Where子句引用了列值分布存在明显偏差的列时:当这种偏差相当明显时,以至于 WHERE 子句中的值将会使优化器选择不同的执行计划。这时应该使用直方图来帮助优化器来修正执行路径。(注意:如果查询不引用该列,则创建直方图没有意义。这种错误很常见,许多 DBA 会在偏差列上创建柱状图,即使没有任何查询引用该列。)
(2)、当列值导致不正确的判断时:这种情况通常会发生在多表连接时,例如,假设我们有一个五项的表联接,其结果集只有 10 行。Oracle 将会以一种使第一个联接的结果集(集合基数)尽可能小的方式将表联接起来。通过在中间结果集中携带更少的负载,查询将会运行得更快。为了使中间结果最小化,优化器尝试在 SQL 执行的分析阶段评估每个结果集的集合基数。在偏差的列上拥有直方图将会极大地帮助优化器作出正确的决策。如优化器对中间结果集的大小作出不正确的判断,它可能会选择一种未达到最优化的表联接方法。因此向该列添加直方图经常会向优化器提供使用最佳联接方法所需的信息。
四.直方图有两种类别,等频直方图与等高直方图。
默认的,如果一个倾斜列上的唯一值超过了254个,那么ORACLE会对此列建立等高直方图,否则建立等频直方图。
通过如下方式,建立表TAB,更新字段B,让列B产生倾斜。并在B列上创建索引。
SQL> spool d:\hist.txt
SQL> create table tab (a number, b number);
表已创建。
SQL>
SQL> begin
2 for i in 1..10000 loop
3 insert into tab values (i, i);
4 end loop;
5 commit;
6 end;
7 /
PL/SQL 过程已成功完成。
SQL> update tab set b=5 where b between 6 and 9995;
已更新9990行。
SQL> commit;
提交完成。
SQL> create index ix_tab_b on tab(b);
索引已创建。
然后分析表,强制使列B不产生直方图。
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'SCOTT',
TABNAME => 'TAB',
CASCADE => TRUE,
METHOD_OPT => 'FOR COLUMNS B SIZE 1 ');
END;
查看视图USER_TAB_HISTOGRAMS,列B上只有最大值,最小值两条记录分别对应端点号(endpoint_number)0和1,这种显示说明列B没有直方图信息。
SQL>SELECT table_name,column_name,endpoint_number,endpoint_value FROM USER_TAB_HISTOGRAMS WHERE TABLE_NAME='TAB' ;
TABLE_NAME COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------ ---------------------------------------- --------------- --------------
TAB B 0 1
TAB B 1 10000
在没有直方图的情况下,在B列上进行等值查询的时候,都是索引范围扫描。
SQL> select * from tab where b=1;
执行计划
----------------------------------------------------------
Plan hash value: 439197569
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 6000 | 4 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1000 | 6000 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TAB_B | 1000 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
SQL> select * from tab where b=5;
已选择9991行。
执行计划
----------------------------------------------------------
Plan hash value: 439197569
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1000 | 6000 | 4 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1000 | 6000 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TAB_B | 1000 | | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
收集直方图信息。看看是什么效果。由于列B唯一值的个数没有超过254因此产生的是等频直方图。
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'SCOTT',
TABNAME => 'TAB',
CASCADE => TRUE,
METHOD_OPT => 'FOR ALL COLUMNS SIZE AUTO ');
END;
在B=1时候采用索引扫描,而B=5时候,已经采用全表扫描了,说明直方图起了作用。
SQL> select * from tab where b=1;
执行计划
----------------------------------------------------------
Plan hash value: 439197569
----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 6 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TAB | 1 | 6 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IX_TAB_B | 1 | | 1 (0)| 00:00:01 |
----------------------------------------------------------------------------------------
SQL> select * from tab where b=5;
已选择9991行。
执行计划
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9991 | 59946 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TAB | 9991 | 59946 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------
查看此时的直方图信息:
SQL>SELECT TABLE_NAME, COLUMN_NAME, ENDPOINT_NUMBER, ENDPOINT_VALUE FROM USER_TAB_HISTOGRAMS
WHERE TABLE_NAME = 'TAB';
TABLE_NAME COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------ ---------------------------------------- --------------- --------------
TAB B 1 1
TAB B 2 2
TAB B 3 3
TAB B 4 4
TAB B 9995 5
TAB B 9996 9996
TAB B 9997 9997
TAB B 9998 9998
TAB B 9999 9999
TAB B 10000 10000
其中EDNPOINT_NUMBER是累计值。EDNPOINT_VALUE是列的值。可以看出这种等频直方图统计的列的信息是非常精确的。它为每一个列值分配了一个桶。从执行计划的ROWS部分也可以看出ORACLE计算出来的cardinality是9991,和实际的情况完全吻合。
如果想知道每一个列值对应的数量是多少,需要做一下简单的减法运算:
假如想知道列值等于5的个数,那么可以通过:
9995-4=9991得到。这就是ENDPOINT_NUMBER累计值的含义。
在看看等高直方图的情况。
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'SCOTT',
TABNAME => 'TAB',
CASCADE => TRUE,
METHOD_OPT => 'FOR COLUMNS B SIZE 8 ');
END;
由于列B有10个唯一值,通过上面的size 8可以强制ORACLE使用等高直方图。
查看直方图信息.
SQL>SELECT TABLE_NAME, COLUMN_NAME, ENDPOINT_NUMBER, ENDPOINT_VALUE FROM USER_TAB_HISTOGRAMS
WHERE TABLE_NAME = 'TAB';
TABLE_NAME COLUMN_NAME ENDPOINT_NUMBER ENDPOINT_VALUE
------------------------------ ---------------------------------------- --------------- --------------
TAB B 0 1
TAB B 7 5
TAB B 8 10000
从查询结果惊奇的发现只有三个桶0 7 8,原来ORACLE会自动省去EDNPOINT_VALUE值相同且ENDPOINT_NUMBER相邻的桶的值。
省去了桶(EDNPOINT_NUMBER)为1 2 3 4 5 6 ,EDNPOINT_VALUE为5的六条内容。
说明:在等高直方图中,EDNPOINT_NUMBER代表桶号,这一点与等频直方图不同。
再看等高直方图下的执行计划:
SQL> select * from tab where b=5;
已选择9991行。
执行计划
----------------------------------------------------------
Plan hash value: 1995730731
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 9982 | 59892 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TAB | 9982 | 59892 | 6 (0)| 00:00:01 |
--------------------------------------------------------------------------
有没有发现什么?
执行计划的ROWS部分,ORACLE计算出来的cardinality不是特别精确的。9991才是精确值。而等频直方图可以精确到9991,因此可以说等频直方图比等高直方图稳定,精确。
可是现实很多时候,列的唯一值是超过254的。只能使用等高直方图了。
相关推荐
#### 11.2 Oracle数据库何时创建直方图(When Oracle Database Creates Histograms) 如果使用`DBMS_STATS`工具为表收集统计信息,并且查询引用了该表中的列,则Oracle数据库会根据之前的查询工作负载自动按需创建...
Oracle直方图是数据库优化的重要工具,特别是在Oracle关系型数据库中,它对于Cost-Based Optimizer (CBO)的成本估算起到关键作用。直方图能够帮助CBO更准确地理解数据表列的数据分布,从而制定出更高效的查询执行...
在图像处理领域,直方图是一种非常重要的工具,它能够帮助我们理解图像的色彩分布情况。直方图提取是分析图像特征的一种基本方法,尤其在颜色分类、图像增强和对比度调整等方面有着广泛的应用。本教程将介绍如何使用...
计算方向梯度直方图(Histograms of Oriented Gradients, HOG)是一种在计算机视觉领域广泛应用的特征提取方法,特别是在行人检测上取得了显著的效果。该技术由Dalal和Triggs在2005年的经典论文《Histograms of ...
"人体检测梯度方向直方图 Histograms of Oriented Gradients for Human Detection" 人体检测是计算机视觉和机器学习领域中的一个核心问题,旨在检测和识别图像或视频中的行人。 Histograms of Oriented Gradients ...
[imOut,hist] = matchHistograms(img1,img2,nbins) 使用用户指定的 bin 数量将 image1 的直方图与图像 2 的直方图匹配。 返回直方图匹配的图像及其直方图。 对两个灰度、两个二进制或两个彩色图像进行操作。 ...
基于Matlab直方图Histogram的人脸识别程序-Processed histogram based Face Recognition.part2.rar 基于Matlab 直方图Histogram的人脸识别程序 因为数据库图片太大,所以分成几个压缩文件。 Face ...
基于Matlab直方图Histogram的人脸识别程序-Processed histogram based Face Recognition.part3.rar 基于Matlab 直方图Histogram的人脸识别程序 因为数据库图片太大,所以分成几个压缩文件。 Face ...
本资源“Color-histograms.rar”提供了一个C语言实现的图像彩色直方图比较方法,帮助开发者进行图像相似度的计算。下面将详细阐述图像彩色直方图、图像相似度的概念以及如何通过直方图比较来衡量图像的相似性。 **...
HOG descriptors 是应用在计算机视觉和图像...这种方法跟边缘方向直方图(edge orientation histograms)、尺度不变特征变换(scale-invariant feature transform descriptors)以及形状上下文方法( shape contexts)
Initially, this idea was based on color histograms that were launched by swain [1]. This algorithm presents the first part of our proposed technique named as “Histogram processed Face Recognition” ...
基于Matlab直方图Histogram的人脸识别程序-Processed histogram based Face Recognition.part1.rar 基于Matlab 直方图Histogram的人脸识别程序 因为数据库图片太大,所以分成几个压缩文件。 Face ...
基于Matlab直方图Histogram的人脸识别程序-Processed histogram based Face Recognition.part4.rar 基于Matlab 直方图Histogram的人脸识别程序 因为数据库图片太大,所以分成几个压缩文件。 Face ...
本文介绍了一种基于空间梯度直方图(Histograms of Oriented Gradients, HOG)的行人检测方法。此方法旨在提高行人检测的速度和准确性,特别适用于计算机视觉领域的应用。 #### 方法原理 **空间梯度直方图(HOG)**...
直方图是一种常用的数据统计工具,在图像处理和计算机视觉等领域中扮演着重要的角色。直方图可以用于快速描述数据的分布特性,如颜色、灰度值等,通常用于图像检索、分割、检测以及跟踪等任务。直方图的计算复杂性是...
文章介绍了一种基于梯度方向直方图(Histograms of Oriented Gradients, HOG)特征的多核跟踪算法,旨在解决目标跟踪过程中常见的光线变化和部分遮挡问题。 #### 二、关键技术点详解 ##### 1. 梯度方向直方图 (HOG...
本文主要讨论了直方图均衡化和规定化处理图像增强技术,并给出了相关的推导公式和算法;同时用matlab语言加以实现。
归一化累积色度直方图(Normalized Cumulative Hue Histograms)是一种统计图像中色相分布的工具。直方图记录了各个色相区间内的像素数量,而归一化则使得不同图像的色相分布可以进行比较。累积直方图则进一步提供了...