`
Jcat
  • 浏览: 49585 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

初步理解直方图

 
阅读更多
引用
当系统中的某些表存在高度不均匀的数据分布时,使用直方图能够产生更好的选择性评估,从而产生更加优化的执行计划。


通过下面的例子来感受直方图的作用

基础数据
drop user sure cascade;
create user sure identified by oracle;
grant resource to sure;
create table sure.tab (a number, b number);


插入1万条数据
begin
for i in 1..10000 loop
insert into sure.tab values (i, i);
end loop;
commit;
end;
/


制造不均匀的情况
update sure.tab set b=5 where b between 6 and 9995;
commit;


此时b列的数据分布为
select b, count(*) from sure.tab group by b order by b;
         B   COUNT(*)
---------- ----------
         1          1
         2          1
         3          1
         4          1
         5       9991
      9996          1
      9997          1
      9998          1
      9999          1
     10000          1
    

【1】在创建索引之前,无论是查询b=1或者是b=5,都只能走全表扫描
explain plan for select * from sure.tab where b=1;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    26 |     6   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TAB  |     1 |    26 |     6   (0)| 00:00:01 |
--------------------------------------------------------------------------


explain plan for select * from sure.tab where b=5;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  9991 |   253K|     6   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TAB  |  9991 |   253K|     6   (0)| 00:00:01 |
--------------------------------------------------------------------------


【2】在b列上创建一个索引
create index sure.ix_tab_b on sure.tab(b);

explain plan for select * from sure.tab where b=1;
select * from table(dbms_xplan.display);
----------------------------------------------------------------------------------------
| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |     1 |    26 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| TAB      |     1 |    26 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IX_TAB_B |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------
   - dynamic sampling used for this statement
18 rows selected.


explain plan for select * from sure.tab where b=5;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |  9991 |   253K|     6   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| TAB  |  9991 |   253K|     6   (0)| 00:00:01 |
--------------------------------------------------------------------------
   - dynamic sampling used for this statement
17 rows selected


网上的例子说,在有了索引以后,应该都走INDEX RANGE SCAN,但是实际情况(10201)却是,b=5时,依然选择到了正确的路径--全表扫描。这是因为没有统计信息,Oracle进行了动态采样,相当于临时收集了一小份统计信息,所以这时反而挺准的。

【3】收集统计信息,但不收集直方图
analyze table sure.tab compute statistics;

与统计信息相关的视图
select num_rows, blocks, empty_blocks, avg_space, chain_cnt, avg_row_len
from dba_tables where table_name = 'TAB';
  NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE  CHAIN_CNT AVG_ROW_LEN
---------- ---------- ------------ ---------- ---------- -----------
     10000         20            4       2080          0          10
   
col low_value format a16  
col high_value format a16
col column_name format a16
select column_name, num_distinct, low_value, high_value, density, num_buckets
from dba_tab_columns where table_name = 'TAB';
COLUMN_NAME      NUM_DISTINCT LOW_VALUE        HIGH_VALUE          DENSITY NUM_BUCKETS
---------------- ------------ ---------------- ---------------- ---------- -----------
A                       10000 C102             C302                  .0001           1
B                          10 C102             C302                     .1           1

select table_name, column_name, endpoint_number, endpoint_value
from dba_tab_histograms where table_name = 'TAB';
TABLE_NA COLUMN_NAME      ENDPOINT_NUMBER ENDPOINT_VALUE
-------- ---------------- --------------- --------------
TAB      B                              0              1
TAB      A                              0              1
TAB      B                              1          10000
TAB      A                              1          10000


观察执行计划
explain plan for select * from sure.tab where b=1;
select * from table(dbms_xplan.display);
----------------------------------------------------------------------------------------
| 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 |
----------------------------------------------------------------------------------------


explain plan for select * from sure.tab where b=5;
select * from table(dbms_xplan.display);
----------------------------------------------------------------------------------------
| 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=5的查询反而跑偏了

【4】创建tab表b列的柱状图统计信息,使得优化器能够知道该列每个值的具体分布情况。
analyze table sure.tab compute statistics for columns b size 10;

直方图中的ENDPOINT_VALUE表示列值,ENDPOINT_NUMBER表示累积的行数。
select table_name, column_name, endpoint_number, endpoint_value
from dba_histograms where table_name = 'TAB';
TABLE_NA 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
TAB      A                              0              1
TAB      A                              1          10000


观察执行计划
explain plan for select * from sure.tab where b=1;
select * from table(dbms_xplan.display);
----------------------------------------------------------------------------------------
| 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 |
----------------------------------------------------------------------------------------


explain plan for select * from sure.tab where b=5;
select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| 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 |
--------------------------------------------------------------------------


【总结】对于b=5的查询来说,全表扫描比之索引范围扫描更加合理,有直方图,优化器就可以做出正确的判断。(没有统计信息,因为动态采样而选对路径,属于歪打正着)

分享到:
评论
1 楼 Jcat 2015-07-21  
如果使用唯一值数量来创建直方图,Oracle为每个值创建一个bucket;但是假如实际的生产系统中,不能够为每一个唯一值分配一个bucket时,Oracle采用合适的算法尽可能将值平均分布到每个bucket中,剩余的值放入到最后的bucket。

相关推荐

    ArcGIS教程:创建直方图

    1. **直观性**:由于直方图以图形的形式展示数据分布,使得读者能够一目了然地理解数据的基本特征,如中心趋势、分布形态等。 2. **适用于大数据集**:对于大量的数据点,直方图能够有效地将其分组,并通过不同高度...

    基于CCS的数字图像直方图均衡化的设计

    ### 基于CCS的数字图像直方图均衡化的设计 #### 一、引言 数字图像处理技术是现代信息技术的重要组成部分,在诸多领域发挥着关键作用,包括但不限于医学成像、遥感技术、生物医学工程、刑事侦查及军事侦察等。其中...

    图像处理——显示直方图

    在实验目的中,除了熟悉MFC操作和图像处理理论,还包括对直方图统计和显示的初步理解。具体的知识点包括: 1. 图像的存储和显示机制,即如何将图像数据加载到内存并呈现到屏幕上。 2. 直方图的概念,如何根据像素的...

    打印输入单词的水平和垂直直方图

    首先,我们需要理解直方图的概念。直方图是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。在这个问题中,我们用每个条形的长度来代表单词的长度,从而可视化数据。 1. **用户输入处理**: ...

    行业分类-设备装置-基于求直方图变化率的直方图分界方法.zip

    这份资料对于理解直方图分界在设备装置行业的应用具有很高的参考价值,能够帮助读者深入理解如何利用图像处理技术进行设备分类和识别。 总之,基于直方图变化率的直方图分界方法是图像处理中的一个重要技术,特别是...

    数字工程直方图.docx

    对于大数据集来说,直方图是进行初步数据分析的有效工具之一。通过对数据进行分组并绘制直方图,可以快速了解数据的整体分布特征,如数据是否呈现出正态分布、偏态分布等特性。 #### 2.3 质量控制 在制造业中,利用...

    数据可视化技术应用-直方图有实操.pptx

    6. **美化和分析**:可以通过改变颜色、添加数据表、趋势线等来进一步美化直方图,同时根据直方图的形状(如正态分布、偏斜分布等)进行初步的数据分析。 直方图在数据分析中有多种应用场景。例如,在教育领域,...

    QC七大手法之五(直方图)_品质管理品管.ppt

    2. 直方图的形状(如山形图)可用于初步判断产品工程是否正常。 3. 比较产品规格分布与目标标准,了解实际与期望的差距。 4. 根据需要考虑进一步的数据细分。 总结来说,直方图是质量管理和控制中不可或缺的工具,...

    时频数直方图PPT学习教案.pptx

    《时频数直方图》的学习教案主要探讨了如何通过数据可视化来理解并分析一组数据的分布情况,尤其是针对学生课外阅读喜好和学习成绩的统计。时频数直方图是统计学中一种重要的数据表示方法,尤其适用于大量数据的分组...

    matlab-基于直方图优化处理的图像去雾算法matlab仿真-源码

    本项目是基于MATLAB实现的一种图像去雾算法的仿真,主要运用了直方图优化处理的方法。MATLAB作为一款强大的数学计算软件,常被用于科学计算、图像处理和信号处理等多个领域。 直方图均衡化是一种常见的图像增强技术...

    用Excel作数据的频率分布表和直方图.docx

    频率分布表和直方图在互联网和计算机科学(cs)领域中非常有用,它们可以帮助我们更好地理解数据集的分布情况,识别异常值,以及进行初步的数据探索。通过Excel提供的工具,即使非专业的数据分析师也能轻松地完成...

    直方图和正态分布PPT学习教案.pptx

    理解直方图和正态分布对于数据的探索性分析至关重要,它们可以帮助我们识别数据的异常值、分布对称性、集中趋势以及数据是否符合正态假设。在实际应用中,这两个工具经常结合使用,例如通过绘制直方图来初步判断数据...

    从直方图数据中寻找规律.pptx

    为了更好地理解数据,我们需要对其进行进一步的分析,如图形化展示,也就是创建直方图。 直方图是一种统计图形,它将数据分为若干个等间距的区间(组),然后计算每个区间的频数(数据点的数量),用条形的高度来...

    经验分布函数与直方图PPT学习教案.pptx

    【经验分布函数与直方图】是统计学中用于数据分布分析的重要概念,它们在处理实际问题时,尤其是在没有先验知识的情况下,帮助我们理解数据的分布情况。 首先,我们来详细探讨经验分布函数(Empirical Distribution...

    程序中包括常见的BLOB分析,包括灰度直方图实时变换,阈值分割,轮廓跟踪,种子填充,圆心的两种求法,对图像处理的入门者有一定的帮助

    例如,灰度直方图可以用来优化阈值选择,阈值变换则能实现对象的初步分离;轮廓跟踪和种子填充进一步细化了对象边界;而圆心的计算则是识别特定形状的重要步骤。这些技术是图像处理和计算机视觉领域不可或缺的基础...

    Python绘制频率分布直方图的示例

    在数据分析领域,频率分布直方图特别适用于探索性数据分析(EDA)中的初步数据理解阶段,帮助分析师快速了解数据的整体形状、中心趋势以及异常值的存在。 #### 二、Python绘制直方图的方法 Python 中最常用的库为 ...

    图像相似度_hist相似度_getrgbhist_RGB图像相似度_

    例如,可以先用直方图交叉核对作为初步筛选,再用SSIM或其他复杂指标进行精细化比较。 总的来说,"getrgbhist"方法是获取RGB图像直方图的关键步骤,而利用直方图进行图像相似度计算则涉及到多种数学方法和技术。...

    图像处理实验报告图像分割

    - **实现原理**:选取灰度直方图中两峰之间的谷对应的灰度值作为阈值,将图像中的像素根据灰度值是否超过该阈值分为两类,从而实现图像的初步分割。 - **实验步骤**: - 读取原始图像并显示。 - 计算并显示原始...

    图像搜索(java源码)

    2. **直方图计算**:在Java中,可以使用`BufferedImage`类和`ColorConvertOp`来读取和转换图像,然后通过遍历所有像素并统计每个颜色区间内的像素数量来构建颜色直方图。 3. **特征提取**:直方图可以被视为图像的...

Global site tag (gtag.js) - Google Analytics