oracle里的统计信息
1 oracle里的统计信息
Oracle的统计信息是这样的一组数据,存储在数据字典,从多个维度描述了oracle数据库对象的详细信息,有6种类型
表的统计信息:记录数、表块的数量、平均行长度等
索引的统计信息:索引的层级、叶子块的数量、聚簇因子等
列的统计信息:列的distinct、为null的数量、列的最小值、最大值及直方图信息
系统的统计信息:所在的数据库服务器的系统处理能力、包含cpu跟I/O
数据字典统计信息:数据库字典基表、表上的索引
内部对象统计信息:内部表X$系列表的详细信息
存放的系统数据字典
(1). DBA_TABLES
(2). DBA_OBJECT_TABLES
(3). DBA_TAB_STATISTICS
(4). DBA_TAB_COL_STATISTICS
(5). DBA_TAB_HISTOGRAMS
(6). DBA_INDEXES
(7). DBA_IND_STATISTICS
(8). DBA_CLUSTERS
(9). DBA_TAB_PARTITIONS
(10). DBA_TAB_SUBPARTITIONS
(11). DBA_IND_PARTITIONS
(12). DBA_IND_SUBPARTITIONS
(13). DBA_PART_COL_STATISTICS
(14). DBA_PART_HISTOGRAMS
(15). DBA_SUBPART_COL_STATISTICS
(16). DBA_SUBPART_HISTOGRAMS
2 oracle里收集与查看统计信息的方法
2.1收集统计信息
2种命令analyze跟dbms_stats包来收集
2.1.1 用analyze来收集统计信息
analyze table EMP compute statistics;
SQL> create table t2 as select * from dba_objects;
SQL> create index idx_t2 on t2(object_id); Index created. SQL> analyze index idx_t2 delete statistics;
--删除该索引的统计信息
Index analyzed. SQL> select count(*) from t2; COUNT(*)
----------
56007 SQL> analyze table t2 estimate statistics sample 15 percent for table;
--以估算模式,采样比例为15%,现在只有表有统计信息,index跟列都还么有,这时的统计信息不准确(估算)
Table analyzed.
SQL> analyze table t2 compute statistics for table ;
--计算表的真实统计信息
Table analyzed. SQL> analyze table t2 compute statistics for columns object_name,object_id;
对表t2 的2个列收集统计信息
Table analyzed.
--对同一个对象而言新执行的analyze会抹去上一个analyze的结果
SQL> analyze table t2 compute statistics for table for columns object_name,object_id;
--同时收集表和列的统计信息
Table analyzed.
SQL> analyze index idx_t2 compute statistics;
--收集该索引的统计信息
Index analyzed.
SQL> analyze table t2 compute statistics;
-一次收集表,列,索引的统计信息
Table analyzed.
2.2.2 用包来收集统计信息
EXEC dbms_stats.gather_table_stats(ownname => USER,tabname => 'EMP');
Oracle 10g以后创建index后,oracle会自动收集目标索引的统计信息
Dbms_stats包最常用的4个存储过程
gather_table_stats:收集目标表、列和表上的index的统计信息
gather_index_stats:收集指定index的统计信息
gather_schema_stats:收集指定schema下的所有对象的统计信息
exec dbms_stats.gather_schema_stats(OWNNAME=>'SOCIALDIAL',ESTIMATE_PERCENT=>100)
gather_database_stats:收集全库对象的统计信息
exec dbms_stats.gather_database_stats(ESTIMATE_PERCENT=>100)
exec dbms_stats.gather_table_stats(OWNNAME IN VARCHAR2, TABNAME IN VARCHAR2, PARTNAME IN VARCHAR2, ESTIMATE_PERCENT IN NUMBER, BLOCK_SAMPLE IN BOOLEAN, METHOD_OPT IN VARCHAR2, DEGREE IN NUMBER, GRANULARITY IN VARCHAR2, CASCADE IN BOOLEAN, STATTAB IN VARCHAR2, STATID IN VARCHAR2, STATOWN IN VARCHAR2,NO_INVALIDATE IN BOOLEAN, STATTYPE IN VARCHAR2, FORCE IN BOOLEAN
先删除t2表的统计信息
SQL> analyze table t2 delete statistics;
Table analyzed.
1 表
SQL> exec dbms_stats.gather_table_stats(OWNNAME=>'GRSV5',TABNAME=>'T2',ESTIMATE_PERCENT=>15, METHOD_OPT=>'FOR TABLE', CASCADE=> FALSE);
--估算模式,采用比例15%
PL/SQL procedure successfully completed.
修改为计算模式ESTIMATE_PERCENT=>100%或者null
2 指定列
METHOD_OPT:’for columns size 1 object_name,object_id’—对指定列收集
3 指定index
--收集指定index的统计信息
exec dbms_stats.gather_index_stats(OWNNAME=>'GRSV5', INDNAME=>'IDX_T2', ESTIMATE_PERCENT=>100);
4 删除
--删除表,列,索引的统计信息
exec dbms_stats.delete_table_stats(OWNNAME=>'GRSV5',TABNAME=>'T2');
2.1.3analyze跟dbms_stats包的区别
1 Analyze命令可以只收集列而不收集表的统计信息,dbms_stats做不到
2 Analyze命令不能正确的收集分区表的统计信息
3 Analyze命令不能并行收集统计信息
4 dbms_stats只能收集与CBO相关的统计信息
2.2 查看统计信息
2.2.1查看表的统计信息
SELECT NUM_ROWS, --表中的记录数
BLOCKS, --表中数据所占的数据块数
EMPTY_BLOCKS, --表中的空块数
AVG_SPACE, --数据块中平均的使用空间
CHAIN_CNT, --表中行连接和行迁移的数量
AVG_ROW_LEN --记录的平均长度
FROM USER_TABLES where table_name='DEPT';
2.2.2 查看列的统计信息
SELECT TABLE_NAME,COLUMN_NAME,
NUM_DISTINCT, --唯一值的个数
LOW_VALUE, --列上的最小值
HIGH_VALUE, --列上的最大值
DENSITY, --选择率因子(密度)
NUM_NULLS, --空值的个数
NUM_BUCKETS, --直方图的BUCKET个数
HISTOGRAM --直方图的类型
FROM USER_TAB_COLUMNS where table_name='T2';
2.2.3 查看index的统计信息
SELECT BLEVEL, --索引的层数
LEAF_BLOCKS, --叶子结点的个数
DISTINCT_KEYS, --唯一值的个数
AVG_LEAF_BLOCKS_PER_KEY, --每个KEY的平均叶块个数
AVG_DATA_BLOCKS_PER_KEY, --每个KEY的平均数据块个数
CLUSTERING_FACTOR --群集因子
FROM USER_INDEXES where index_name='IDX_T2';
3 表的统计信息
create table test (id number,name varchar2(10)); declare
i number;
begin
for i in 1..10000 loop
insert into test
values(100,'hongquan');
end loop;
commit;
end ; select dump(100,16),dump('hongquan',16) from dual;
Typ=2 Len=2: c2,2 Typ=96 Len=8: 68,6f,6e,67,71,75,61,6e
--100,hongquan存储在db数据块的行占用字节+描述其长度的1字节
exec dbms_stats.gather_table_stats(OWNNAME=>'GRSV5',TABNAME=>'TEST',ESTIMATE_PERCENT=>100);
--收集表的统计信息
10000行记录一模一样,所有表的AVG_ROW_LEN=3+9
10000 28 0 0 0 12
--CBO会根据该统计信息来评估全部扫描的成本
统计信息的不准会导致sql性能问题
4 索引的统计信息
1 包含index的层级,叶子块的数量,聚簇因子等典型的维度
Blevel存储的是目标索引的层级(表示从根节点到目标叶子块的深度,用于cbo计算访问index 的成本),其值越大,访问的数据块就会越多,从0开始计算,
在oracle里,要降低目标index 的层级,可以通过rebuild来实现
analyze index IDX_T2 validate structure;
--分析索引结构
select name,height,lf_rows,lf_blks,del_lf_rows from index_stats where name='IDX_T2'
IDX_T2 2 56007 124 0
--删除表的大部分记录
delete from t2 where rownum<=55000
--再次分析并查询
IDX_T2 2 56007 124 55000
--再重新rebuildindex
alter index IDX_T2 rebuild;
--查询结果
IDX_T2 1 2 1 0
lf_blks:被CBO用于计算目标index做索引全扫描(index full scan)和索引范围扫描(index range scan)的成本
2 聚簇因子-clustering_factor
聚簇因子是指按照索引键值排序的索引行和存储对应表中数据行的存储顺序的相似程度(初始值为1)
Oracle首先定位到目标索引处于最左边的叶子块
从最左边的叶子块开始扫描,
聚簇因子高的索引走索引范围扫描比聚簇因子低的要耗费等多的物理io
在oracle中,能够降低目标索引的聚簇因子的唯一方法就是对表中数据按照目标索引的索引键值排序后重新存储
Cob计算索引范围扫描 cost=io cost + cpu cost
手动设置表的聚簇因子
exec dbms_stats.set_index_stats(OWNNAME =>'GRSV5',INDNAME =>'IDX_T2',clstfct =>10000,no_invalidate=>false);
5 列的统计信息
5.1 列的统计信息的含义和种类
Distinct、null、min、max
create table t2 as select * from dba_objects;
select count(*) from t2 where DATA_OBJECT_ID is null;
--对表t2 不收集直方图信息的统计信息
EXEC dbms_stats.gather_table_stats(ownname => 'GRSV5',tabname => 'T2',ESTIMATE_PERCENT=>100, METHOD_OPT=>'FOR ALL COLUMNS SIZE 1');
--查看其信息
SELECT * FROM DBA_TAB_COL_STATISTICS WHERE table_name='T2' AND COLUMN_NAME='DATA_OBJECT_ID';
5.2 列的统计信息不准导致谓词越界的实例
可以找到统计信息中的最大值跟最小值
exec dbms_stats.convert_row_value('',:temp);
输入的值是否在存在的值范围内,
--重新收集统计信息
5.3 直方图—histogram
Cbo默认目标列的min_value跟max_value是均匀分布的
例1
create table t2 (a number(5),b varchar2(5)); declare
cnt number(5) :=1;
begin
loop
insert into t2 values(1,1); if cnt =10000 then
exit;
end if; cnt:=cnt+1;
end loop;
insert into t2 values (2,2);
commit;
end; select b,count(*) from t2 group by b; create index idx_t2_b on t2(b); EXEC dbms_stats.gather_table_stats(ownname => 'GRSV5',tabname => 'T2',ESTIMATE_PERCENT=>100, METHOD_OPT=>'FOR ALL COLUMNS SIZE 1'); explain plan for
select * from t2 where b=''; select * from table(dbms_xplan.display);
--------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 5001 | 25005 | 6 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| T2 | 5001 | 25005 | 6 (0)| 00:00:01 |
--cbo 默认b列上均匀分布,b列只有2个值,返回的cardinality为5001
这时候需要收集直方图信息
--收集直方图信息
EXEC dbms_stats.gather_table_stats(ownname => 'GRSV5',tabname => 'T2',ESTIMATE_PERCENT=>100, METHOD_OPT=>'FOR COLUMNS SIZE 100 B');
----- FOR COLUMNS SIZE AUTO B—对b列自动收集直方图信息
| 0 | SELECT STATEMENT | | 1 | 5 | 2 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| T2 | 1 | 5 | 2 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_T2_B | 1 | | 1 (0)| 00:00:01 |
1 直方图的种类
Frequence:直方图的bucket的数量就等于目标列的distinct值的数量
Frequence类型的直方图所对应的bucket的数量不能超过254(12c中取消)
SELECT * FROM DBA_TAB_COL_STATISTICS WHERE table_name='T2' AND COLUMN_NAME='B';
Height balanced直方图:相对而言,可以收集大于254行的distinct
5.3 直方图的收集方法
在包dbms_stats中的method_opt参数来指定
Method_opt参数:
For all [index |hidden |columns [size_clause]---所有列
For columns [size_clause] column|attribute ----部分列
Size格式:1-254范围的整数(1表示删除该目标的直方图信息)
Repeat只对已经有直方图统计信息的列收集
Auto让oracle自行决定是否对目标列收集
Skewonly只对数据分布不均匀的列收集
直方图的影响:对cbo估算可选择率,进而对计算成本、选择执行计划有直接影响
5.4 只用直方图的注意事项
1 直方图是专门为了分布不均匀的目标列的可选择率吗,如果分布均匀,或者有pk,unique根本不需要收集直方图信息
2 对于那些没有在where条件中出现的列,不管是否均匀,都不需要收集
3直方图统计信息可鞥会影响shared cursor的共享
4主要收集策略
6全局统计信息
全局统计信息对分区表、分区索引才有意义
针对分区表的sql,除非其查询条件限定了待访问的数据只在部分分区上,否则在大多数情况下都需要全局统计信息才能 正确的执行计划
Oracle的全局统计信息只能通过dbms_stats包来收集(参数:granularity来指定全局统计信息的统计策略,
Granularity:global(表)、partition(分区)、subpartition(子分区)、global and partition(表+分区)、all、auto
Auto是默认值,oracle会根据分区表的类型来决定统计信息的收集级别
select DBMS_STATS.GET_PARAM('granularity') from dual;
AUTO—查看其默认值
dbms_stats.delete_table_stats—可以删除分区表上的三个级别的统计信息
7 动态采样
作用:1oracle使用了动态采样,不管sql语句各列有什么的关联关系,大多数情况下,cbo都能相对正确的估算整个where条件的组个可选择率
2 一定程度上解决临时表没有统计信息而导致cbo错选择执行计划
动态采样仅适合于那些针对单表或者多表关联的第一个驱动表的select、update、delete语句
参数optimizer_dynamic_sampling的值>=1,10g默认是2
8多列统计信息(11g)
Method_opt“for columns(n1,n2) size auto”
9系统统计信息
用来描述oracle数据库所在服务器的系统处理能力的辅助统计信息,cpu的主频、单读块的平均消耗时间、多快读的平均消耗时间和单次多快读所能读取的数据块的平均值
dbms_stats.gather_system_stats('start');
dbms_stats.gather_system_stats('stop');
--系统统计信息在表AUX_STATS$
select * from sys.AUX_STATS$
数据字典、内部对象的统计信息X$表
10 oracle里的自动收集统计信息
Oracle 10g开始引入自动收集统计信息作业,能够每天自动收集统计信息,该作业会判断:1 需要对那些对象收集统计信息,2 需要对哪些统计信息已经过期的对象重复收集统计信息,3以估算模式收集统计信息的采样比例,4 需要对哪些列收集直方图信息,5是否启用并行收集以及相应的并行度
参数statistics_level的值为typical或者all,
select job_name,program_name,schedule_name from dba_scheduler_jobs where job_name='GATHER_STATS_JOB'
GATHER_STATS_JOB GATHER_STATS_PROG MAINTENANCE_WINDOW_GROUP
10g 中自动统计信息作业可配置维护的窗口
select * from dba_scheduler_wingroup_members where window_group_name='MAINTENANCE_WINDOW_GROUP'
MAINTENANCE_WINDOW_GROUP WEEKNIGHT_WINDOW
MAINTENANCE_WINDOW_GROUP WEEKEND_WINDOW
--查询近几次收集记录
select * from (select* from dba_scheduler_job_run_details where job_name='GATHER_STATS_JOB' order by log_date desc ) where rownum<=4;
----10g中的该job只有2个可维护的窗口,可以无限制的消耗系统资源
----11g中取消了该job,引用GATHER_STATS_PROG
Insert+delete+update所影响的记录超过tab$中记录表的记录数的10%,或者目标表执行过truncate操作,oracle自认为该表的统计信息失效,自动收集该表的统计信息
10g中禁用job 来收集
exec dbms_scheduler.disable9\('GATHER_STATS_JOB')
锁定与解锁表的统计信息
analyze table IDD_CHANNEL compute statistics for table for all indexes;
ORA-38029: object statistics are locked
--解锁表的统计信息
exec dbms_stats.unlock_table_stats(ownname=>'CLOUDAPI',tabname=>'IDD_CHANNEL');
--锁定表的统计信息
exec dbms_stats.lock_table_stats(ownname=>'CLOUDAPI',tabname=>'IDD_CHANNEL');
schema 针对用户
oracle里的统计信息的更多相关文章
- 基于Oracle的SQL优化(崔华著)-整理笔记-第5章“Oracle里的统计信息”
第5章“Oracle里的统计信息” 详细介绍了Oracle数据库里与统计信息相关的各个方面的内容,包括 Oracle数据库中各种统计信息的分类.含义.收集和查看方法,以及如何在Oracle数据库里正确 ...
- Oracle性能优化之Oracle里的统计信息
一.什么是统计信息 oracle数据库里的统计信息是如下的一组数据:他们存储在数据字典里,且从多个维度描述了oracle数据库数据对象的详细信息. oracle数据库里的统计信息主要分为以下6种情况: ...
- Oracle的自动统计信息不收集直方图的信息
Oracle的自动统计信息不收集直方图的信息 在oracle9i中,默认的统计信息收集是不收集直方图信息的,也就是说默认的MOTHOD_OPT模式为FOR ALL COLUMNS SIZE 1 在10 ...
- Oracle之自动收集统计信息
一.Oracle 11g 在Oracle的11g版本中提供了统计数据自动收集的功能.在部署安装11g Oracle软件过程中,其中有一个步骤便是提示是否启动这个功能(默认是启用这个功能). 在这里介绍 ...
- 关于Oracle开启自动收集统计信息的SPA测试
主题:关于Oracle开启自动收集统计信息的SPA测试 环境:Oracle RAC 11.2.0.4(Primary + Standby) 需求:生产Primary库由于历史原因关闭了自动统计信息的收 ...
- Oracle重新获取统计信息以及SQLSERVER重建索引
Oracle重新获取统计信息 exec dbms_stats.gather_schema_stats(ownname =>'LCoe739999',options => 'GATHER', ...
- Oracle 手动收集统计信息
收集oracle统计信息 优化器统计范围: 表统计: --行数,块数,行平均长度:all_tables:NUM_ROWS,BLOCKS,AVG_ROW_LEN: 列统计: --列中唯一值的数量(NDV ...
- oracle表的统计信息完全正确,执行计划无故改变。原厂人员如是回复
就像在电话里提到的那样,Oracle内部的优化器是根据一系列的内部算法基于表上的统计信息来产生执行计划的.对于特别复杂的SQL语句,Oracle的优化器有一定几率不能得到最优的执行计划(因为机器代码实 ...
- Oracle中的统计信息
一.什么是统计信息 统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息.例如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于 ...
随机推荐
- The 2014 ACM-ICPC Asia Mudanjiang Regional Contest
The 2014 ACM-ICPC Asia Mudanjiang Regional Contest A.Average Score B.Building Fire Stations C.Card G ...
- 负载均衡之DNS域名解析
转载请说明出处:http://blog.csdn.net/cywosp/article/details/38017027 在上一篇文章(http://blog.csdn.net/cywosp/arti ...
- Java 子类实例化对象的过程
子类实例化是否会实例化父类? 不会.父类在子类实例化过程中是并没有被实例化,java中new子类没有实例化父类,只是调用父类的构造方法初始化了,子类从父类继承来的属性,这个调用是子类的对象调用的父类的 ...
- 用requests库爬取猫眼电影Top100
这里需要注意一下,在爬取猫眼电影Top100时,网站设置了反爬虫机制,因此需要在requests库的get方法中添加headers,伪装成浏览器进行爬取 import requests from re ...
- mysql数据库(一):建表与新增数据
一. 学习目标 理解什么是数据库,什么是表 怎样创建数据库和表(create) 怎样往表里插入数据(insert) 怎样修改表里的数据(update) 怎样删除数据库,表以及数据(delete) 二. ...
- idea的常用设置
1.官网 官网:http://www.jetbrains.com/idea/download/#section=windows 官方文档:http://www.jetbrains.com/help/i ...
- 51nod-1636-dp
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1636 1636 教育改革 题目来源: CodeForces 基准时间限制 ...
- 状态管理(Vuex、 Flux、Redux、The Elm Architecture)
1.https://vuex.vuejs.org/zh-cn/intro.html (vuex) 这就是 Vuex 背后的基本思想,借鉴了 Flux.Redux.和 The Elm Architect ...
- IOS-RunTime应用
什么是Runtime 总结起来,iOS中的RunTime的作用有以下几点: 1.发送消息(obj_msgSend) 2.方法交换(method_exchangeImplementations) 3.消 ...
- python----异常处理(二)
格式如下: try: pass except Exception as e:#如果上面出错,执行下面代码 pass else:#try如果没出错执行此下面代码 pass fin ...