对象统计信息描写叙述数据是如何在数据库中存储的,查询优化器使用这些统计信息来做出正确的决定。Oracle中有三种类型的对象统计信息:表统计、列统计和索引统计。而在每种类型中,有细分为:表或索引级别的统计、分区级别统计和子分区级别的统计,后面两种仅仅有在对象被分区和具有子分区的情况下才可用。

统计信息相关视图

表统计信息

表/索引级别的统计

user_tab_statistics
user_tables

分区级别的统计

user_tab_statistics
user_tab_partitions

子分区级别统计

user_tab_statistics
user_tab_subpartitions

列统计信息

表/索引级别的统计

user_tab_col_statistics
user_tab_histograms

分区级别的统计

user_part_col_statistics
user_part_histograms

子分区级别统计

user_subpart_col_statistics
user_subpart_histograms

索引统计信息

表/索引级别的统计

user_ind_statistics
user_indexes

分区级别的统计

user_ind_statistics
user_ind_partitions

子分区级别统计

user_ind_statistics
user_ind_subpartitions

创建測试表

这里将创建測试表T用于后面对统计信息的说明。

创建測试表

create table test as
select rownum as id,
round(dbms_random.normal * 1000) as val1,
100 + round(ln(rownum / 3.25 + 2)) as val2,
100 + round(ln(rownum / 3.25 + 2)) as val3,
dbms_random.string('p', 250) as pad
from all_objects
where rownum <= 1000
order by dbms_random.value

上面的语句创建了一个1000行的表,然后我们将val1列中的负值清空:

update test set val1 = null where val1 < 0;

为測试表加入主键和索引

alter table test add constraint test_pk primary key (id);
create index test_val1 on test (val1);
create index test_val2 on test (val2);

为測试表收集统计信息

begin
dbms_stats.gather_table_stats(ownname => user,
tabname => 'TEST',
estimate_percent => 100,
method_opt => 'for all columns size skewonly',
cascade => TRUE);
end;

表统计信息

以下是表统计信息中的keyword段:

select num_rows, blocks, empty_blocks, avg_space, chain_cnt, avg_row_len
from user_tab_statistics
where table_name = 'TEST'; NUM_ROWS BLOCKS EMPTY_BLOCKS AVG_SPACE CHAIN_CNT AVG_ROW_LEN
----------------------------------------------------------------------------------
1000 39 0 0 0 265

以下是对字段含义的解释:

1)num_rows:表中数据的行数;
2)blocks:高水位线以下的数据块个数(高水位线详见“Oracle性能分析4:数据訪问方法之全扫描”http://blog.csdn.net/tomato__/article/details/38981425);
3)empty_blocks:高水位线以上的数据块个数。因为dbms_stats不计算该值,因此为0;
4)avg_space:表里数据块的平均空暇空间(字节),因为dbms_stats不计算该值,因此为0。
5)chain_cnt:涉及行链接和行迁移的总行数,因为dbms_stats不计算该值,因此为0(详见“Oracle行迁移和行链接”http://blog.csdn.net/tomato__/article/details/40146573);
6)avg_row_len:表中平均每一个记录的长度(字节)。

列统计信息

以下是列统计信息的最重要的统计信息字段:

select column_name,
num_distinct,
low_value,
high_value,
density,
num_nulls,
avg_col_len,
histogram,
num_buckets
from user_tab_col_statistics
where table_name = 'TEST';

以下是对这些字段的解释:
 1)num_distinct:该列中不同值的数量;
 2)low_value:该列的最小值。显示为内部存储的格式,对于字符串列仅仅存储前32字节;
 3)high_value:该列的最大值。

显示为内部存储的格式,对于字符串列仅仅存储前32字节;
 4)density:0到1之间的一个小数。

接近0表示对于列的过滤操作能去掉大多数行。接近1表示对于该列的过滤操作起不到什么作用。
 假设没有直方图,该值的计算方法为:density=1/num_distinct。

 假设有直方图,则依据不同的直方图类型有不同的计算方法。
 5)num_nulls:该列中存储的NULL的总数;
 6)avg_col_len:平均列大小,以字节表示;
 7)histogram:表明是否有直方图统计信息,值包含:NONE(没有)、FREQUENCY(频率类型)和HEIGHT BALANCED(平均分布类型);
 8)num_buckets:直方图里的bucket的数量,最小为1,最大为254。
注:low_value和high_value表示为内部存储的格式,以下的存储过程能够得到test表的全部列的最大最小值:

declare
l_val1 test.val1%type;
begin
for v in (select low_value, high_value
from user_tab_col_statistics
where table_name = 'TEST') loop
dbms_stats.convert_raw_value(v.low_value, l_val1);
dbms_output.put_line('low value : ' || l_val1);
dbms_stats.convert_raw_value(v.high_value, l_val1);
dbms_output.put_line('low value : ' || l_val1);
end loop;
end;

直方图

查询优化器须要找到满足条件的数据行数,假设列的数据均匀分布的,则非常easy依据最小值、最大值和唯一值总数就能够计算得到,这些信息在列统计信息中就能够得到。

但假设数据不是均匀分布的。查询优化器则须要额外的信息才干做出正确估算。

这些查询优化器须要的关于数据不均匀分布的额外信息叫做直方图,存在两种类型的直方图:频度直方图(frequency histogram)和等高直方图(height-balanced histogram)。

频度直方图

频度直方图的本质特性例如以下:
 1)桶数(即分类数)等于唯一值总数。

对于每一个桶来说。视图user_tab_histograms有一行数据与之相应。
 2)列endpoint_value提供该值本身。

该列为number类型。应此非数字类型的列必须要进行转换,仅仅取前六个字节。这意味着直方图中存储的值的分布是基于列的前面部分。因而。固定前缀的字符串会使直方图的分布严重不均衡;
 3)列endpoint_number是取值的累积出现次数。当前的endpoint_number减去上一个endpoint_number,就是当前行这个值的出现次数。

通过以下的方式就能够得到列val2的频次:

select column_name,
endpoint_value,
endpoint_number,
endpoint_number - lag(endpoint_number, 1, 0) over(order by endpoint_number) as frequency
from user_tab_histograms
where table_name = 'TEST'
and column_name = 'VAL2'
order by endpoint_number COLUMN_NAME ENDPOINT_VALUE ENDPOINT_NUMBER FREQUENCY
-------------------------------------------------------
VAL2 101 8 8
VAL2 102 33 25
VAL2 103 101 68
VAL2 104 286 185
VAL2 105 788 502
VAL2 106 1000 212

以下用test表作为一个样例说明优化器如何利用频度直方图精确估算查询返回的行数:

explain plan set statement_id '101' for select * from test where val2 = 101;
explain plan set statement_id '102' for select * from test where val2 = 102;
explain plan set statement_id '103' for select * from test where val2 = 103;
explain plan set statement_id '104' for select * from test where val2 = 104;
explain plan set statement_id '105' for select * from test where val2 = 105;
explain plan set statement_id '106' for select * from test where val2 = 106;

然后我们查看运行计划对返回行数的估算:

select statement_id,cardinality from plan_table where id = 0;

STATEMENT_ID	CARDINALITY
----------------------------------
101 8
102 25
103 68
104 185
105 502
106 212

等高直方图

当一列的唯一值数量总是大于桶的同意最大数量(254)时,就不能使用频度直方图了,这是就仅仅能使用等高直方图了。
等高直方图的主要特征例如以下:
 1)桶数少于唯一值总数。除非被压缩,否则相应于每一个桶。视图user_tab_histograms里都有一个包含端点号(endpoint number)的行与之相应,端点号0表明最小取值。
 2)端点值(endpoint_value)就是列的数值。因为该列是number类型,非数字类型必须进行转换。此值仅取前六个字节;
 3)endpoint_number列给出了桶号;
 4)直方图不存储一个取值的频度。
等高直方图仅仅存储列值属于某一个桶,假设有两个列值位于同一个桶,则当中一个将被忽略(压缩),这种统计就可能导致估算不准确。在实践中,等高直方图不但可能导致错误的估算,还可能引起查询优化器估值的不稳定。

索引统计信息

以下的查询能够得到索引统计信息:

select index_name,
blevel,
leaf_blocks,
distinct_keys,
num_rows,
clustering_factor,
avg_leaf_blocks_per_key,
avg_data_blocks_per_key
from user_ind_statistics
where table_name = 'TEST';

主要字段的含义例如以下:
 1)blevel:为了訪问叶子块而须要读取的分支块的数量,包含根块。
 2)leaf_blocks:索引中的叶子块数;
 3)distinct_keys:索引中的唯一键值总数。
 4)num_rows:索引中的键值数;
 5)clustering_factor:见“Oracle性能分析8:使用索引”http://blog.csdn.net/tomato__/article/details/39294655;
 6)avg_leaf_blocks_per_key:存放一个键值的平均叶子块数,公式例如以下;
 avg_leaf_blocks_per_key = leaf_blocks/distinct_keys
 7)avg_data_blocks_per_key:表中单个键引用的平均数据块数,公式例如以下:
 avg_data_blocks_per_key = clustering_factor/distinct_keys

Oracle性能分析12:对象统计信息的更多相关文章

  1. Oracle性能分析11:系统统计信息

    早期Oracle查询优化器的开销计算是基于运行SQL语句所须要的物理读,这种方法被叫做I/O开销模式(I/O cost model),这种方法的主要缺点是觉得单块读和多块读开销相当.在Oracle 8 ...

  2. Oracle 判断 并 手动收集 统计信息 脚本

    CREATE OR REPLACE PROCEDURE SchameB.PRC_GATHER_STATS AUTHID CURRENT_USER IS BEGIN SYS.DBMS_STATS.GAT ...

  3. Oracle性能分析7:创建索引

    在创建索引时,我们往往希望可以预估索引大小,以评估对现有project环境的影响,我们也希望创建索引的过程可以最小化的影响我们正在执行的project环境,并能查看索引的状况. 预估索引大小 预估索引 ...

  4. Oracle 和 SQLSERVER 重新获取统计信息的方法

    1. Oracle 重新获取统计信息的命令 exec dbms_stats.gather_schema_stats(ownname =>) # 需要修改 ownername options 指定 ...

  5. [Oracle] 11G自己主动收集统计信息

    在11g中,默认自己主动收集统计信息的时间为晚上10点(周一到周五,4个小时),早上6点(周六,周日,20个小时),例如以下所看到的: select a.window_name, a.repeat_i ...

  6. 启用oracle 11g自己主动收集统计信息

    今天接到朋友数据库一个case,在DBCA建库时,把自己主动收集统计信息的选项去掉了,数据库执行半年没有收集过统计信息.如今要启用方法例如以下: exec DBMS_AUTO_TASK_ADMIN.E ...

  7. Oracle性能分析1:开启SQL跟踪和获取trace文件

    当Oracle查询出现效率问题时,我们往往须要了解问题所在,这样才干针对问题给出解决方式.Oracle提供了SQL运行的trace信息,当中包括了SQL语句的文本信息.一些运行统计,处理过程中的等待, ...

  8. Oracle性能分析3:TKPROF简介

    tkprof它是Oracle它配备了一个命令直插式工具,其主要作用是将原始跟踪文件格文本文件的类型,例如,最简单的方法,使用下面的: tkprof ly_ora_128636.trc ly_ora_1 ...

  9. Oracle 性能分析

    1.--查出耗时长的 10条SQL select * from (select v.sql_id, v.child_number, v.sql_text, v.elapsed_time, v.cpu_ ...

随机推荐

  1. sqlserver 小计合计总计

    SELECT CASE WHEN GROUPING(F1) = 1 THEN '总计'WHEN GROUPING(F1) = 0 AND GROUPING(F2) = 1 THEN  F1+'合计'W ...

  2. 洛谷P1976 鸡蛋饼

    题目背景 Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟.经过一番逼问,小 x 道出 了实情:因为他喜欢圆. 题目描述 最近小 x 又发现了一个关于圆的有趣的问题:在圆上有2N 个不同的点 ...

  3. java(运算符,控制流程语句,函数 )

    运算符 数据类型转换: 小数据类型-------->大数据类型(自动类型转换) 大数据类型--------->小数据类型(强制类型转换) 强制类型转换的格式: 小数据类型  变量名 = ( ...

  4. JOISC 2017 Day1 T3 烟花棒

    JOISC 2017 Day1 T3 烟花棒 题意: ​ 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...

  5. c#程序打包、机器代码生成(Ngen.exe)

    深入本机影像生成器(Ngen.exe)工具使用方法详解 先介绍一点背景知识:.Net程序在运行时会实时(JIT)编译,将.Net程序文件编译成cpu认识的汇编机器码.实时编译需要消耗额外的cpu和内存 ...

  6. Java基础学习总结(21)——常用正则表达式列表

    很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求.所以我最近把开发中常用的一些正则表达式整理了一下,包括校验数字.字符.一些特殊的需求等等.给自己留个 ...

  7. 使用Ant打包Android应用具体解释——Ant使用解析

    上篇<使用Ant打包Android应用具体解释>描写叙述了使用Ant打包的流程,但非常多步骤并没有说明如此做的原因,本篇将从Ant方面来理解,下一篇从APK生成的流程来说明. APK包的生 ...

  8. AIX中经常使用的SMIT 的使用

    AIX中经常使用的SMIT 的使用 1.  smit 的日志文件 (1)$HOME/smit.log      记录了所訪问的全部菜单.对话内容,所运行的命令和输出结果 在 SMIT 会话中出现的全部 ...

  9. C# Find() 与 FindAll()方法的使用

    Find()   :检索与指定匹配的第一个元素 FindAll()   : 检索与指定匹配的所有元素 如:List<string> strList=new List<string&g ...

  10. CentOS 7最小化安装图解

    一.环境介绍: win10 x64安装VMware® Workstation 14 Pro(版本:14.1.2 build-8497320) 二.安装CentOS 1.新建虚拟机 打开虚拟机,主页,创 ...