zoukankan      html  css  js  c++  java
  • [统计信息系列4] 列的统计信息

    image


    (一)列的统计信息查看

    列的统计信息,主要包含了列的distinct值的数量、列的null值数量、列的最小值、列的最大值等,这些统计信息存储在SYS.HIST_HEAD$中,可以通过数据字典查看:

    • DBA_TAB_COL_STATISTICS:查看表的列统计信息
    • DBA_PART_COL_STATISTICS:查看分区表的分区列的统计信息
    • DBA_SUBPART_COL_STATISTICS:查看分区表的子分区的列的统计信息

    上述表中核心字段:

    NUM_DISTINCT:目标列distinct值的数量

    NUM_NULLS:目标列NULL值的数量

    LOW_VALUEHIGH_VALUE:分别存储列的最小值和最大值,CBO用它来评估对目标列做范围查询时的可选择率。当列上没有直方图时,用目标列做范围查询的可选择率(selectivity)公式如下:

         (1)目标列指定大于VAL,且VAL在LOW_VALUE和HIGH_VALUE之间:

           selectivity = ((HIGH_VALUE - VAL) / (HIGH_VALUE - LOW_VALUE)) * Null_Adjust Null_Adjust = (NUM_ROWS - NUM_NULLS) / NUM_ROWS

         (2)目标列指定小于VAL,且VAL在LOW_VALUE和HIGH_VALUE之间:

           selectivity = ((VAL - LOW_VALUE) / (HIGH_VALUE - LOW_VALUE)) * Null_Adjust Null_Adjust = (NUM_ROWS - NUM_NULLS) / NUM_ROWS

    DENSITY:目标列的密度,与直方图有关

    NUM_BUCKETS:目标列桶的数量,与直方图有关


    (二)列的历史统计信息查看

    列的历史统计信息可以通过AWR Repository的基表SYS.Wri$_Optstat_Histhead_History来查看。


    (三)直方图

    (1)直方图的含义

    在Oracle数据库中,CBO会默认为目标列的数据在其最小值LOW_VALUE与最大值HIGH_VALUE之间是均匀分布的,并且会按照均匀分布原则来计算对目标列施加查询条件后的可选择率selectivity和集的Cardinality,据此计算成本并选择执行计划。然而,在实际生产环境中,有些列的数据是分布不均匀的、甚至是极度倾斜的,对于这样的列,如果还按照均匀分布的原则去计算可选择率与cardinality,并据此计算成本、选择执行计划,那么CBO所选的执行计划可能是不合理的。

    为了解决这个问题,Oracle引入了直方图(HISTOGRAM),直方图是一种列的统计信息,描述了目标列数据分布情况。如果对目标列收集了直方图,则意味着CBO不在认为该目标列上的数据是均匀分布的了,CBO会利用直方图信息来计算可选择率和cardinality,进而计算成本并选择合适的执行计划。


    (2)直方图查看

    直方图数据存储在基表SYS.HISTOGRAM中,可以通过数据字典来查看:

    • DBA_TAB_HISTOGRAMS:查看表的直方图统计信息
    • DBA_PART_HISTOGRAMS:查看表分区的直方图统计信息
    • DBA_SUBPART_HISTOGRAMS:查看表子分区的直方图统计信息

    如果要查看列是否收集了直方图,可以使用DBA_TAB_COL_STATISTICS、DBA_PART_COL_STATISTICS、DBA_SUBPART_COL_STATISTICS的“HISTOGRAM”字段来查看。


    (3)直方图类型

    (3.1)频率(Frequency)直方图

    存储在数据字典里描述Bucket的数量等于目标列distinct值的数量,这种类型的直方图称为频率直方图。频率直方图对应的Bucket数量不能超过254,即列的distinct的值要小于254。在12C中不再有这一限制。

    什么情况下Oracle会去收集列的直方图信息呢?Oracle只对那些在where中使用过的列收集直方图统计信息,Oracle会在SYS.COL_USAGE$中记录各个表的列使用情况,在自动收集直方图信息时会去查询SYS.COL_USAGE$,如果发现没有目标列的使用记录,就不会收集该列的统计信息。

    对于Frequency直方图,DBA_TAB_HISTOGRAMS中ENDPOINT_NUMBER和ENDPOINT_VALUE的含义如下:

    ENDPOINT_VALUE:代表每个distinct的值

    ENFPONIT_NUMBER:是一个累加值,可以使用一条记录的ENFPONIT_NUMBER减去上一条记录的ENFPONIT_NUMBER值来得到ENDPOINT_VALUE值的记录数。

    例如:test02表中,col1列的值分布如下

    clipboard

    则其直方图信息如下,ENDPOINT_VALUE为‘a’的有10条记录,ENDPOINT_VALUE为‘a’和‘b’的有10010条记录,通过求差,可以知道ENDPOINT_VALUE为‘b’的有10000条记录。

    clipboard


    (3.2)高度(Height Balanced)直方图

    存储在数据字典里描述Bucket的数量小于目标列distinct值的数量,这种类型的直方图称为高度直方图。在Oracle 12C之前,如果目标列的distinct值大于254,Oracle只能对列收集Height Balanced直方图。

    高度直方图的数据是如何分布的呢?对于频率(Frequency)直方图,每个Bucket存储一个distinct的值,但是对于高度(High Balanced)直方图,Oracle首先会根据目标列的记录从小到大排序,然后用目标表总的记录数除以Bucket的数量,来决定每个Bucket需要描述的记录数。Bucket编号从0开始,0号Bucket的ENDPOINT_VALUE记录的是目标列的最小值,其余Bucket的ENDPOINT_VALUE描述的是该Bucket中的最大值。

    对于Height Balanced直方图,DBA_TAB_HISTOGRAMS中ENDPOINT_NUMBER和ENDPOINT_VALUE的含义如下:

    ENFPONIT_NUMBER:Bucket的编号

    ENDPOINT_VALUE:该Bucket里面的最大值

    例如:test04表中,col1列的值分布如下

    先插入10000笔数据,其中col1列的值从1到10000,然后再插入10000笔col1等于500的值。如下:

    clipboard

    则其直方图信息如下:

    clipboard

    通过DBA_TAB_COL_STATISTICS可以看到该列有Height Balanced直方图,且有254个Buckets,每个Buckets有约78条记录。对于该列的直方图,解释如下:

    • 0号bucket记录的col1的最小值为1;
    • 1号bucket记录的col1的最大值为79;
    • 2号bucket记录的col1的最大值为158;
    • ...
    • 132号bucket记录的col1的最大值为500,这里需要注意,发现没有7~131号bucket信息,其实是因为7~132号bucket记录的col1的最大值都是500,发生了记录合并。


    (4)直方图收集方法

    在Oracle里面收集直方图的信息,通常是调用DBMS_STATS包里面的GATHER_DATABASE_STATS/GATHER_DICTIONARY_STATS/GATHER_SCHEMA_STATS/GATHER_TABLE_STATS收集统计信息是输入参数METHOD_OPT来实现的。官方文档对该参数的解释如下:

    METHOD_OPT参数控制列的统计信息和直方图统计信息的收集,可以接收以下值

    • FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause]
    • FOR COLUMNS [size clause] column [size_clause] [,column [size_clause]...]

    size_clause 可以是 size_clause := SIZE {integer | REPEAT | AUTO | SKEWONLY}

    column 可以是 column := column_name | extension name | extension

    - integer : 直方图bucket的数量,在[1,254]之间,1代表删除列上的直方图信息

    - REPEAT : 仅仅对之前已经收集过直方图的列进行直方图信息收集

    - AUTO : Oracle自行决定对那些列收集直方图,以及使用哪种类型的直方图,默认收集方式。

    - SKEWONLY : Oracle自行决定对数据分布不均匀的列收集直方图

    - column_name : 对指定的列收集直方图

    - extension : 可以对多列 (column_name, colume_name [, ...]) 或者一个表达式收集直方图


    例子1:对test01表上有索引的所有列以自动的方式收集直方图统计信息

    SQL> EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR ALL INDEXED COLUMNS SIZE AUTO');

    注意:以自动方式收集列的直方图统计信息,Oracle不一定会去收集,如果要强制收集,可以:

    SQL> EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR ALL INDEXED COLUMNS');


    例子2:对test01表上的col4和col5以自动的方式收集统计信息

    SQL> EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR COLUMNS SIZE AUTO COL4 COL5');


    例子3:对test01表上的col1和col2收集直方图统计信息,并指定COL1和COL2的bucket的数量为10

    SQL> EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR COLUMNS SIZE 10 COL1 COL2');

    注意:这里2个列的直方图信息是单独收集的


    例子4:对test01表上的col1和col2收集直方图统计信息,并指定COL1的bucket数量为5,COL2的bucket数量为10

    EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR COLUMNS COL1 SIZE 5 COL2 SIZE 10');


    例子5:删除test01表上所有列的直方图统计信息

    EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR ALL COLUMNS SIZE 1');


    例子6:删除test01表上COL1列的直方图统计信息

    EXEC dbms_stats.gather_table_stats(ownname=> 'LIJIAMAN',tabname=> 'TEST01',method_opt=> 'FOR COLUMNS COL1 SIZE 1');


    (5)直方图使用注意事项

    • 直方图是为了准确评估数据分布不均匀的列而引入的,对于有主见、唯一性索引的列,根本不需要收集直方图;
    • 对于从未在where条件中出现的列,不管数据分布是否均已,不需要收集直方图;
    • 直方图统计信息可能会影响shared cursor的共享,特别在使用绑定变量时,如果列上有直方图信息,可能会产生硬解析,造成子游标过多;


    【完】

  • 相关阅读:
    HTML入门(HB、DW)
    HTML入门(HB、DW)
    数据库流行度6月排行榜:Oracle飙升MySQL止跌回升
    The 'mode' option has not been set, webpack will fallback to 'production' for th is value
    Error: Cannot find module 'webpack/schemas/WebpackOptions.json'
    seafile python api requests
    Linux上复制tomcat启动需要注意的问题
    SQL优化:你真的知道国家字符集的性能影响吗?
    OpenCV3.4.1+VS2017安装教程(WINDOWS10)
    HTML入门(HB、DW)
  • 原文地址:https://www.cnblogs.com/lijiaman/p/12994626.html
Copyright © 2011-2022 走看看