您的位置:首页 > 数据库 > Oracle

oracle 统计信息

2011-03-21 22:26 309 查看
1. 什么是统计信息

统计信息主要是描述数据库中表,索引的大小,规模,数据分布状况等的一类信息。比如,表的行数,块数,平均每行的大小,索引的leaf blocks,索引字段的行数,不同值的大小等,都属于统计信息。CBO正是根据这些统计信息数据,计算出不同访问路径下,不同join 方式下,各种计划的成本,最后选择出成本最小的计划。

统计信息是存放在数据字段表中的,如tab$。一般我们从数据字段视图中察看统计信息状况,如DBA_TABLES,DBA_INDEXES,DBA_TAB_COL_STATISTICS, DBA_TAB_HISTOGRAMS 等。

列举下DBA_TABLES,DBA_INDEXES 视图中表示统计信息的一些字段。这些字段只有搜集过统计信息之后才有值,否则是空的。这些字段中last_analyzed 字段表示上次统计信息搜集的时间,大家可以根据这个字段,快速的了解最近一次统计信息搜集的时间。

--dba_tables

NUM_ROWS* NUMBER Number of rows in the table

BLOCKS* NUMBER Number of used data blocks in the table

EMPTY_BLOCKS* NUMBER Number of empty (never used) data blocks in the table

AVG_SPACE* NUMBER Average amount of free space, in bytes, in a data block allocated to the table

CHAIN_CNT* NUMBER Number of rows in the table that are chained from one data block to another, or which have migrated to a new block, requiring a link to preserve the old ROWID

AVG_ROW_LEN* NUMBER Average length of a row in the table in bytes

LAST_ANALYZED DATE Date on which this table was most recently analyzed

--dba_indexes

BLEVEL* NUMBER B*-Tree level: depth of the index from its root block to its leaf blocks. A depth of 0 indicates that the root block and leaf block are the same.

LEAF_BLOCKS* NUMBER Number of leaf blocks in the index

DISTINCT_KEYS* NUMBER Number of distinct indexed values. For indexes that enforce UNIQUE and PRIMARY KEY constraints, this value is the same as the number of rows in the table (USER_TABLES.NUM_ROWS)

AVG_LEAF_BLOCKS_PER_KEY* NUMBER Average number of leaf blocks in which each distinct value in the index appears, rounded to the nearest integer. For indexes that enforce UNIQUE and PRIMARY KEY constraints, this value is always 1.

AVG_DATA_BLOCKS_PER_KEY* NUMBER Average number of data blocks in the table that are pointed to by a distinct value in the index rounded to the nearest integer. This statistic is the average number of data blocks that contain rows that contain a given value for the indexed columns.

CLUSTERING_FACTOR* NUMBER Indicates the amount of order of the rows in the table based on the values of the index.

• If the value is near the number of blocks, then the table is very well ordered. In this case, the index entries in a single leaf block tend to point to rows in the same data blocks.

• If the value is near the number of rows, then the table is very randomly ordered. In this case, it is unlikely that index entries in the same leaf block point to rows in the same data blocks

NUM_ROWS NUMBER Number of rows in the index

SAMPLE_SIZE NUMBER Size of the sample used to analyze the index

LAST_ANALYZED DATE Date on which this index was most recently analyzed

2. 如何搜集统计信息

统计信息搜集也是有多种方法,推荐大家使用DBMS_STATS 表来进行统计信息搜集及进行一般的统计信息维护工作。

DBMS-STATS 包,主要提供了搜集,删除,导出,导入,修改统计信息的方法,分别对应于gather系列,delete系列,export 系列,import系列,set系列的子过程。一般可能主要是使用统计信息的搜集,以及导出导入这样的功能。具体来说,主要会使用到如下几个子过程:

GATHER_INDEX_STATS Procedure

Gathers index statistics.

GATHER_TABLE_STATS Procedure

Gathers table and column (and index) statistics.

CREATE_STAT_TABLE Procedure

Creates a table with name stattab in ownname's schema which is capable of holding statistics.

EXPORT_TABLE_STATS Procedure

Retrieves statistics for a particular table and stores them in the user stat table.

EXPORT_SCHEMA_STATS Procedure

Retrieves statistics for all objects in the schema identified by ownname and stores them in the user stat table identified by stattab.

IMPORT_INDEX_STATS Procedure

Retrieves statistics for a particular index from the user stat table identified by stattab and stores them in the dictionary.

IMPORT_TABLE_STATS Procedure

Retrieves statistics for a particular table from the user stat table identified by stattab and stores them in the dictionary.

IMPORT_SCHEMA_STATS Procedure

Retrieves statistics for all objects in the schema identified by ownname from the user stat table and stores them in the dictionary.

对于统计信息的搜集,谈谈个人的几点理解:

 统计信息默认是存放在数据字典表中的,也只有数据字典中的统计信息,才会影响到CBO。

 DBMS_STATS 提供的CREATE_STAT_TABLE 过程,只是生成一个用户自定义的特定格式的表,用来存放统计信息罢了,这个表中的统计信息是不会影响到统计信息的。

 GATHER 系列过程中,如果指定stattab,statid,statown 参数(也可以不指定),则是搜集的统计信息除了更新到数据字典外,还在statown 用户下的stattab 表中存放一份,标示为 statid;

 EXPORT和IMPORT 系列的过程中,stattab,statid,statown 参数不能为空,分别表示把数据字典中的当前统计信息导出到用户自定义的表中,以及把用户表中的统计信息导入到数据字典中,很明显可以看出,这里的导入操作和上面GATHER 操作会改变统计信息,可能会引起执行执行计划的改变,因此要慎重操作。

 每次统计信息搜集前,将旧的统计信息备份起来是很有必要的;特别是保留一份或多份系统在稳定时期的统计信息也是很有必要的。

 多长时间搜集一次统计信息,对于统计信息如何备份和保留,搜集统计信息时如何选择合适的采样,并行,直方图设置等都比较重要,需要设计一个较好的统计信息搜集策略。

统计信息包括下面几类:

表统计:包括记录数、block数和记录平均长度。

列统计:列中不同值的数量(NVD)、空值的数量和数据分布(HISTOGRAM)。

索引统计:索引叶块的数量、索引的层数和聚集因子(CLUSTERING FACTOR)。

系统统计:I/O性能和利用率和CPU性能和利用率。

生成统计信息:

统计信息生成技术包括三种:

基于数据采样的估计方式;

精确计算方式;

用户自定义的统计信息收集方式;

其中采用估算方式可以指定总记录数的估算百分比或者总块数的估算百分比。

分区表的统计信息分为几级:分区表的整体信息、分区的统计信息和子分区的统计信息。

最常用的收集统计信息的方式包括:DBMS_STATS包和ANALYZE语句,Oracle推荐使用DBMS_STATS包来收集统计信息。

DBMS_STATS包中用于收集统计信息的过程包括:

dbms_stats.gather_table_stats 收集表、列和索引的统计信息;

dbms_stats.gather_schema_stats 收集SCHEMA下所有对象的统计信息;

dbms_stats.gather_index_stats 收集索引的统计信息;

dbms_stats.gather_system_stats 收集系统统计信息。

dbms_stats.delete_table_stats 删除表的统计信息

dbms_stats.export_table_stats 输出表的统计信息

dbms_stats.create_state_table

dbms_stats.set_table_stats 设置 表的统计

dbms_stats.auto_sample_size

dbms_stats.gather_database_stats:收集数据库中所有对象的统计信息;

在CREATE INDEX和ALTER INDEX REBUILD时可以指定COMPUTE STATISTICS语句,对于非分区表重建索引时会收集表、列和索引的统计信息。对于分区表,只收集索引信息,不会收集表和列信息。

可以在将METHOD_OPT参数设置为“FOR ALL HIDDEN COLUMNS SIZE N”来收集函数索引的索引表达式信息。

Oracle根据下列条件来决定使用哪些索引:

索引中的记录数;

索引中不同键值的数量;

索引的层数;

索引中的叶块数;

聚集因子;

每个键值平均叶块数;

如果两个索引的选择性、查询代价和集势都相同,那么优化器会根据索引名称的字母顺序选

使用analyze命令收集oracle统计信息

ORACLE数据库的PL/SQL语句执行的优化器,有基于代价的优化器(CBO)和基于规则的优化器(RBO)。

RBO的优化方式,依赖于一套严格的语法规则,只要按照规则写出的语句,不管数据表和索引的内容是否发生变化,不会影响PL/SQL语句的"执行计划"。

CBO自ORACLE7版被引入,ORACLE自7版以来采用的许多新技术都是只基于CBO的,如星型连接排列查询,哈希连接查询,反向索引,索引表,分区表和并行查询等。CBO计算各种可能"执行计划"的"代价",即cost,从中选用cost最低的方案,作为实际运行方案。各"执行计划"的cost的计算根据,依赖于数据表中数据的统计分布,ORACLE数据库本身对该统计分布是不清楚的,须要分析表和相关的索引,才能搜集到CBO所需的数据。

CBO是ORACLE推荐使用的优化方式,要想使用好CBO,使SQL语句发挥最大效能,必须保证统计数据的及时性。

统计信息的生成可以有完全计算法和抽样估算法。SQL例句如下:

完全计算法: analyze table abc compute statistics;

抽样估算法(抽样20%): analyze table abc estimate statistics sample 20 percent;

对表作完全计算所花的时间相当于做全表扫描,抽样估算法由于采用抽样,比完全计算法的生成统计速度要快,如果不是要求要有精确数据的话,尽量采用抽样分析法。建议对表分析采用抽样估算,对索引分析可以采用完全计算。

我们可以采用以下两种方法,对数据库的表和索引及簇表定期分析生成统计信息,保证应用的正常性能。

1. 在系统设置定时任务,执行分析脚本。

在数据库服务器端,我们以UNIX用户oracle,运行脚本analyze,在analyze中,我们生成待执行sql脚本,并运行。(假设我们要分析scott用户下的所有表和索引)

Analyze脚本内容如下:

sqlplus scott/tiger << EOF

set pagesize 5000

set heading off

SPOOL ANALYTAB.SQL

SELECT "ANALYZE TABLE SCOTT."||TABLE_NAME||" ESTIMATE STATISTICS SAMPLE 20 PERCENT ;" FROM USER_TABLES;

SPOOL OFF

SPOOL ANALYIND.SQL

SELECT "ANALYZE TABLE SCOTT."||TABLE_NAME||" ESTIMATE STATISTICS SAMPLE 20 PERCENT FOR ALL INDEXES;" FROM USER_TABLES;

SPOOL OFF

SPOOL ANALYZE.LOG

@ANALYTAB.SQL

@ANALYIND.SQL

SPOOL OFF

EXIT

在UNIX平台上crontab加入,以上文件,设置为每个月或合适的时间段运行。

或者将如下脚本保存成analyze.sql,然后在sqlplus里面执行:

set pagesize 5000

set linesize 300

set trims on

set heading off

set feedback off

SPOOL analyTab.sql

SELECT 'ANALYZE TABLE ZFMI.'||TABLE_NAME||' COMPUTE STATISTICS ;'

FROM USER_TABLES;

SPOOL OFF

SPOOL analyIdx.sql

SELECT 'ANALYZE TABLE ZFMI.'||TABLE_NAME||' COMPUTE STATISTICS

FOR ALL INDEXES;' FROM USER_TABLES;

SPOOL OFF

SPOOL analyLog.log

@@analyTab.sql

@@analyIdx.sql

SPOOL OFF

2. 利用ORACLE提供的程序包(PACKAGE)对相关的数据库对象进行分析。

有以下的程序包可以对表,索引,簇表进行分析。

包中的存储过程的相关参数解释如下:

TYPE可以是:TABLE,INDEX,CLUSTER中其一。

SCHEMA为:TABLE,INDEX,CLUSTER的所有者,NULL为当前用户。

NAME为:相关对象的名称。

METHOD是:ESTIMATE,COMPUTE,DELETE中其一,当选用ESTIMATE,

下面两项,ESTIMATE_ROWS和ESTIMATE_PERCENT不能同时为空值。

ESTIMATE_ROWS是:估算的抽样行数。

ESTIMATE_PERCENT是:估算的抽样百分比。

METHOD_OPT是:有以下选项,

FOR TABLE /*只统计表*/

[FOR ALL [INDEXED] COLUMNS] [SIZE N] /*只统计有索引的表列*/

FOR ALL INDEXES /*只分析统计相关索引*/

PARTNAME是:指定要分析的分区名称。

1)

DBMS_DDL.ANALYZE_OBJECT(

TYPE VARCHAR2,

SCHEMA VARCHAR2,

NAME VARCHAR2,

METHOD VARCHAR2,

ESTIMATE_ROWS NUMBER DEFAULT NULL,

ESTIMATE_PERCENT NUMBER DEFAULT NULL,

METHOD_OPT VARCHAR2 DEFAULT NULL,

PARTNAME VARCHAR2 DEFAULT NULL ) ;

该存储过程可对特定的表,索引和簇表进行分析。例如,对SCOTT用户的EMP表,进行50%的抽样分析,参数如下:

DBMS_DDL.ANALYZE_OBJECT("TABLE", "SCOTT", "EMP", "ESTIMATE", NULL,50);

2)

DBMS_UTILITY.ANALYZE_SCHEMA (

SCHEMA VARCHAR2,

METHOD VARCHAR2,

ESTIMATE_ROWS NUMBER DEFAULT NULL,

ESTIMATE_PERCENT NUMBER DEFAULT NULL,

METHOD_OPT VARCHAR2 DEFAULT NULL ) ;

DBMS_UTILITY.ANALYZE_DATABASE (

METHOD VARCHAR2,

ESTIMATE_ROWS NUMBER DEFAULT NULL,

ESTIMATE_PERCENT NUMBER DEFAULT NULL,

METHOD_OPT VARCHAR2 DEFAULT NULL );

其中,ANALYZE_SCHEMA用于对某个用户拥有的所有TABLE,INDEX和CLUSTER的分析统计。ANALYZE_DATABASE用于对整个数据库进行分析统计。

3) DBMS_STATS是在ORACLE8I中新增的程序包,它使统计数据的生成和处理更加灵活方便,并且可以并行方式生成统计数据。在程序包中的以下过程分别分析统计TABLE,INDEX,SCHEMA,DATABASE级别的信息。

DBMS_STATS.GATHER_TABLE_STATS

DBMS_STATS.GATHER_INDEX_STATS

DBMS_STATS.GATHER_SCHEMA_STATS

DBMS_STATS.GATHER_DATABASE_STATS

在这里,我们以数据库JOB的方式,定时对数据库中SCOTT模式下所有的表和索引进行分析:

在SQL*PLUS下运行:

VARIABLE jobno number;

BEGIN

DBMS_JOBS.SUBMIT ( :jobno ,

" dbms_utility.analyze_schema ( "scott", "estimate", NULL, 20) ; ",

sysdate, "sysdate+30");

commit;

end;

/

Statement processed.

Print jobno

JOBNO

-------------

16

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/accpsz/archive/2010/01/08/5155614.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oracle 职场 休闲