`

dbms_stats与analyze分析汇总(原创)

 
阅读更多

dbms_stats

DBMS_STATS.GATHER_TABLE_STATS的语法如下:
DBMS_STATS.GATHER_TABLE_STATS (ownname VARCHAR2, tabname VARCHAR2, partname VARCHAR2, estimate_percent NUMBER,   block_sample BOOLEAN, method_opt VARCHAR2, degree NUMBER, granularity VARCHAR2, cascade BOOLEAN, stattab VARCHAR2, statid VARCHAR2, statown VARCHAR2,   no_invalidate BOOLEAN, force BOOLEAN);

参数说明:
ownname:要分析表的拥有者
tabname:要分析的表名.
partname:分区的名字,只对分区表或分区索引有用.
estimate_percent:采样行的百分比,取值范围[0.000001,100],null为全部分析,不采样. 常量:DBMS_STATS.AUTO_SAMPLE_SIZE是默认值,由oracle决定最佳取采样值.
block_sapmple:是否用块采样代替行采样.
method_opt:决定histograms信息是怎样被统计的
通过设置 method_opt参数可以智能地生成直方图,具体取值如下:
for all columns:10g默认值(根据版本的不同,默认值也会有所差异),统计所有列的histograms.
for all indexed columns:统计所有indexed列的histograms.
for all hidden columns:统计你看不到列的histograms
for columns <list> SIZE <N> | REPEAT | AUTO | SKEWONLY:统计指定列的histograms.N的取值范围[1,254];
REPEAT上次统计过的histograms;
AUTO由oracle决定N的大小;
SKEWONLY选项会耗费大量处理时间,因为它要检查每个索引中的每个列的值的分布情况。
假如dbms_stat发现一个索引的各个列分布得不均匀,就会为那个索引创建直方图,帮助基于代价的SQL优化器决定是进行索引访问,还是进行全表扫描访问。
degree:决定并行度.默认值为null.
granularity:设置分区表收集统计信息的粒度,分别有
all:对表达全局,分区,子分区的数据都做分析
auto:Oracle根据分区的类型,自动决定做哪一种粒度的分析
global:只做全局级别的分析
global and partition:只对全局和分区级别做分析,对子分区不做分析,这是和all的一个区别
partition:只做分区级别做分析
subpartition:只做子分区做分析
exec DBMS_STATS.GATHER_TABLE_STATS(NULL,'T3', GRANULARITY => 'SUBPARTITION', CASCADE => TRUE);
exec DBMS_STATS.GATHER_TABLE_STATS(NULL,'T2', GRANULARITY => 'PARTITION', CASCADE => TRUE);   
exec DBMS_STATS.GATHER_TABLE_STATS(NULL,'T1', GRANULARITY => 'GLOBAL', CASCADE => TRUE);

 

其中,T1为全表,T2为分区,T3为子分区
cascace:是收集索引的信息.默认为falase.
stattab指定要存储统计信息的表;statid如果多个表的统计信息存储在同一个stattab中用于进行区分;statown存储统计信息表的拥有者。以上三个参数若不指定,统计信息会直接更新到数据字典.
no_invalidate: Does not invalidate the dependent cursors if set to TRUE. The procedure invalidates the dependent cursors immediately if set to FALSE.
force:即使表锁住了也收集统计信息.

dbms_stats的使用
dbms_stats包除了gather_table_stats过程外还有如下过程
EXPORT_COLUMN_STATS:导出列的分析信息
EXPORT_INDEX_STATS:导出索引分析信息
EXPORT_SYSTEM_STATS:导出系统分析信息
EXPORT_TABLE_STATS:导出表分析信息
EXPORT_SCHEMA_STATS:导出方案分析信息
EXPORT_DATABASE_STATS:导出数据库分析信息
IMPORT_COLUMN_STATS:导入列分析信息
IMPORT_INDEX_STATS:导入索引分析信息
IMPORT_SYSTEM_STATS:导入系统分析信息
IMPORT_TABLE_STATS:导入表分析信息
IMPORT_SCHEMA_STATS:导入方案分析信息
IMPORT_DATABASE_STATS:导入数据库分析信息
GATHER_INDEX_STATS:分析索引信息
GATHER_TABLE_STATS:分析表信息,当cascade为true时,分析表、列(索引)信息
GATHER_SCHEMA_STATS:分析方案信息
GET_COLUMN_STATS:获取字段的统计信息
GET_SYSTEM_STATS:获取系统的统计信息
GET_INDEX_STATS:获取索引的统计信息
GET_TABLE_STATS:获取表的统计信息
SET_COLUMN_STATS:设置字段的统计信息。通常应用在测试环境,也不排除在极端情况下起到奇效。
SET_SYSTEM_STATS:设置系统的统计信息
SET_INDEX_STATS:设置索引的统计信息
SET_TABLE_STATS:设置表的统计信息
DELETE_COLUMN_STATS:删除字段的统计信息
DELETE_SYSTEM_STATS:删除系统的统计信息
DELETE_INDEX_STATS:删除索引的统计信息
DELETE_TABLE_STATS:删除表的统计信息
DELETE_DATABASE_STATS:删除数据库的统计信息
DELETE_DICTIONARY_STATS:删除数据字典的统计信息
DELETE_SCHEMA_STATS:删除用户方案的统计信息
DELETE_FIXED_OBJECTS_STATS:删除固定对象的统计信息
GATHER_SCHEMA_STATS:分析方案信息
GATHER_DATABASE_STATS:分析数据库信息
GATHER_SYSTEM_STATS:分析系统信息
CREATE_STAT_TABLE:建立存放统计信息的表
DROP_STAT_TABLE:删除存放统计信息的表
LOCK_TABLE_STATS:锁定表的统计信息。当觉得当前统计信息非常好,且表数据几乎不变化时,可以考虑锁定统计信息,锁定之后相关的所有数据分析,包括表级,列级,直方图、索引的分析都将被锁定,不允许被更新。
LOCK_SCHEMA_STATS:锁定用户方案的统计信息
UNLOCK_TABLE_STATS:解锁表的统计信息
UNLOCK_SCHEMA_STATS:解锁用户方案的统计信息
RESTORE_SYSTEM_STATS:还原系统的统计信息
RESTORE_INDEX_STATS:还原索引的统计信息
RESTORE_TABLE_STATS:还原表的统计信息
RESTORE_DATABASE_STATS:还原数据库的统计信息
RESTORE_DICTIONARY_STATS:还原数据字典的统计信息
RESTORE_SCHEMA_STATS:还原用户方案的统计信息
RESTORE_FIXED_OBJECTS_STATS:还原固定对象的统计信息
统计信息还原过程如下
通过dbms_stats.get_stats_history_availability查找分析数据恢复到最早时间点,只有在这个时间点之后的分析数据才可以被恢复。
SQL> select dbms_stats.get_stats_history_availability from dual;

 

GET_STATS_HISTORY_AVAILABILITY
---------------------------------------------------------------------------
12-MAR-12 10.58.17.552941000 AM +08:00

查看最后一次分析表T的时间

 

SQL> select last_analyzed from user_tables where table_name='T';

 

LAST_ANALYZED
------------------
12-APR-12

恢复表T的统计信息
SQL>  exec  dbms_stats.rEstore_table_stats('HR','T','11-APR-12 10.58.17.552941000 AM +08:00');

 

PL/SQL procedure successfully completed.
再次查看最后一次分析表T的时间,恢复成功

 

SQL> select last_analyzed from user_tables where table_name='T';

 

 

 

LAST_ANALYZED
------------------
11-APR-12

 

我们在收集统计信息时,有可能由于统计信息收集错误,而额导致性能下降,这时我们就要保存之前收集的统计信息来快速恢复统计信息。下面就通过具体案例来贯穿dbms_stats的使用

1、首先创建一个分析表,该表是用来保存之前的分析值:
SQL> exec dbms_stats.create_stat_table('HR',stattab=>'STAT_TABLE');
PL/SQL procedure successfully completed.

2、收集表的统计信息:
SQL> exec dbms_stats.gather_table_stats(ownname=>'HR',tabname=>'T',ESTIMATE_PERCENT=>dbms_stats.auto_sample_size,METHOD_OPT=>'FOR ALL INDEXED COLUMNS',DEGREE=>4,CASCADE=>TRUE);
PL/SQL procedure successfully completed.

3、导出表分析信息到stat_table中
SQL> select count(*) from stat_table;
  COUNT(*)
----------
         0
SQL> exec dbms_stats.export_table_stats(ownname=>'HR',TABNAME=>'T',STATTAB=>'STAT_TABLE');
PL/SQL procedure successfully completed.
SQL> select count(*) from  stat_table;
  COUNT(*)
----------
         4

4、删除分析信息
SQL> exec dbms_stats.delete_table_stats(ownname=>'HR',TABNAME=>'T');
PL/SQL procedure successfully completed.

SQL> SELECT num_rows,blocks,empty_blocks as empty, avg_space, chain_cnt, avg_row_len FROM dba_tables WHERE owner = 'TEST'
AND table_name = 'T1';
NUM_ROWS     BLOCKS      EMPTY AVG_SPACE CHAIN_CNT AVG_ROW_LEN
---------- ---------- ---------- ---------- ---------- -----------

没有查到分析数据
5、导入统计信息
SQL> exec dbms_stats.import_table_stats(ownNAME=>'HR',TABNAME=>'T',STATTAB=>'STAT_TABLE');
PL/SQL procedure successfully completed.
SQL> select num_rows,blocks,empty_blocks,avg_space,chain_cnt from user_tables where table_name='T';
  NUM_ROWS     BLOCKS EMPTY_BLOCKS  AVG_SPACE  CHAIN_CNT
---------- ---------- ------------ ---------- ----------
     10104         20            0          0          0

可以查到分析数据

 

ANALYZE
analyze语法如下

 

ANALYZE
  { TABLE [ schema.]table
      [ PARTITION ( partition ) | SUBPARTITION ( subpartition ) ]
  | INDEX [ schema. ]index
      [ PARTITION ( partition ) | SUBPARTITION ( subpartition ) ]
  | CLUSTER [ schema. ]cluster
  }
  { COMPUTE [ SYSTEM ] STATISTICS [for_clause]
  | ESTIMATE [ SYSTEM ] STATISTICS [for_clause][SAMPLE integer { ROWS | PERCENT }]
  | validation_clauses
  | LIST CHAINED ROWS [ into_clause ]
  | DELETE [ SYSTEM ] STATISTICS
  } ;

PARTITION | SUBPARTITION:对分区表或索引进行分析
CLUSTER cluster:对簇进行分析,分析的结果会放在ALL_CLUSTERS, USER_CLUSTERS and DBA_CLUSTERS.
compute_statistics_clause
语法:COMPUTE [ SYSTEM ] STATISTICS [for_clause]
对分析对像进行精确的统计,然后把信息存储的数据字典中。可以选择对表或对字段进行分析。
computed和estimated这两种方式的统计数据都被优化器用来影响sql的执行计划
如果指定system选项就只统计系统产生的信息
for_clause
FOR TABLE:只统计表
FOR COLUMNS:只统计某个字段
FOR ALL COLUMNS:统计所有字段
FOR ALL INDEXED COLUMNS:统计索引的所有字段,如
analyze table t compute statistics for table for all indexed columns size  25;       #size为直方图的桶数
estimate_statistics_clause
ESTIMATE [ SYSTEM ] STATISTICS [for_clause][SAMPLE integer { ROWS | PERCENT }]
只是对部分行做一个大概的统计。适用于大表
SAMPLE:指定具体统计多少行,如果忽略这个参数的话,oracle会默认为1064行
ROWS causes:行数 Oracle to sample integer rows of the table or cluster or integer entries from the index. The integer must be at least 1.
PERCENT causes:百分数,如
ANALYZE TABLE employees ESTIMATE STATISTICS SAMPLE 100 ROWS;
ANALYZE TABLE employees ESTIMATE STATISTICS SAMPLE 15 PERCENT;
validation_clauses
分析REF(游标,动态关联结果集的临时对象)或是对像的结构,如

ANALYZE TABLE employees VALIDATE STRUCTURE CASCADE;
ANALYZE TABLE customers VALIDATE REF UPDATE;

analyze的限制
不可以分析数据字典表
Oracle 9i中不可以分析外部表,但可以用DBMS_STATS来实现这个目的
不可以分析临时表
不可以计算或估计下列字段类型
REFs, varrays, nested tables, LOBs (LOBs are not analyzed, they are skipped), LONGs, or object types.
统计信息相关的视图
对索引进行分析后,分析的结果默认会放在USER_INDEXES, ALL_INDEXES,或 DBA_INDEXES中
分析的内容:
Depth of the index from its root block to its leaf blocks (BLEVEL)
Number of leaf blocks (LEAF_BLOCKS)
Number of distinct index values (DISTINCT_KEYS)
Average number of leaf blocks for each index value (AVG_LEAF_BLOCKS_PER_KEY)
Average number of data blocks for each index value (for an index on a table) (AVG_DATA_BLOCKS_PER_KEY)
Clustering factor (how well ordered the rows are about the indexed values) (CLUSTERING_FACTOR)
对表进行分析后,分析的结果默认会放在USER_TABLES, ALL_TABLES, and DBA_TABLES表中,在分析表的时候,oracle也会分析基于函数的index所引用的表达式
分析的内容:
Number of rows (NUM_ROWS) *
Number of data blocks below the high water mark (that is, the number of data blocks that have been formatted to
receive data, regardless whether they currently contain data or are empty) (BLOCKS)
* Number of data blocks allocated to the table that have never been used (EMPTY_BLOCKS) Average available free
space in each data block in bytes (AVG_SPACE)
Number of chained rows (CHAIN_COUNT) Average row length, including the row's overhead, in bytes (AVG_ROW_LEN)
USER_TAB_COL_STATISTICS:用于存储与列相关的统计信息。
USER_HISTOGRAMS :用于存储与直方图相关的统计信息。

dbms_stats和analyze的使用场景

自dbms_stats推出后,Oracle就强烈建议在收集CBO统计信息时用dbms_stats替代analyze,原因如下:
1、dbms_stats可以并行分析,
可以并行进行,对多个用户,多个Table

2、dbms_stats有自动分析的功能(alter table monitor )
3、analyze 分析分区表时统计信息不准确

4、对于oracle 9里面的External Table,Analyze不能使用,只能使用DBMS_STATS来收集信息。

关于第3点原因是,dbms_stats会实在的去分析表全局统计信息(当指定参数);而analyze是将表分区(局部)的statistics 汇总计算成表全局statistics ,可能导致误差。
如果想分析整个用户或数据库,还可以采用工具包,可以并行分析
Dbms_utility(8i以前的工具包)
Dbms_stats(8i以后提供的工具包),如

dbms_stats.gather_schema_stats(User,estimate_percent=>100,cascade=> TRUE);
dbms_stats.gather_table_stats(User,TableName,degree => 4,cascade => true);

既然dbms_stats相对于analyze有如此之多的优势,是否可以完全废弃analyze命令呢?答案是否定的,现在关于analyze的定位Oracle解释:
Use the ANALYZE statement (rather than DBMS_STATS) for statistics collection not related to the cost-based optimizer,for example:
1、Collect or delete statistics about an index or index partition, table or table partition, index-organized table, cluster, or scalar object attribute.
2、Validate the structure of an index or index partition, table or table partition, index-organized table, cluster, or object reference (REF).
3、Identify migrated and chained rows of a table or cluster.


可以看到analyze已经不是用来收集与CBO相关的统计信息了,而侧重于对象结构的分析。故通常我们会这样使用analyze:
1、通过Validate Structure来分析对象的结构信息, dbms_stats还不能分析对象结构
2、
收集CHAINED ROWS, 收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。可以通过analyze….list chained rows收集块中行链接的信息到chained_rows表中。
注:必须先在执行analyze语句所在的schema内执行$ORACLE_HOME/rdbms/admin/utlchain.sql(或utlchn1.sql)脚本建立chained_rows表。在chained_rows建立之后﹐才能收集行链接信息

3、Analyze table compute statistics 收集表上的 empty_blocks、avg_space 空间使用信息
4、Analyze Cluster 收集簇的信息,其实cluster上唯一可统计的信息是DBA_CLUSTERS.AVG_BLOCKS_PER_KEY(Number of blocks in the table divided by number of cluster keys) ,

三个注意点

1、当某个索引处于monitoring usage的时候,如果使用dbms_stats去分析表并且同时分析索引,oracle会调用gather_index_stat来分析索引,需要用到索引名,故会将该索引的v$object_usage.USED设置为TRUE。analyze 虽然分析了索引,但是其实只需要obj#,不会将索引状态设置为USE = TRUE
2、dbms_stats无法分析cluster表,分析cluster表仍然需要analyze

3、如果无法执行analyze命令,请验证是否创建了 存放验证信息的表,创建命令如下
@?/rdbms/admin/utlvalid.sql               

 

参考至:《让Oracle跑得更快》谭怀远著
            http://www.itpub.net/thread-845777-1-1.html

            http://www.cnblogs.com/tracy/archive/2011/07/19/2110508.html
            http://www.cnblogs.com/sopost/archive/2011/02/20/2190045.html

            http://blog.chinaunix.net/uid-7332142-id-249531.html

            http://www.itpub.net/thread-1344276-1-1.html
            https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=BULLETIN&id=237397.1
            https://support.oracle.com/CSP/main/article?cmd=show&type=NOT&doctype=BULLETIN&id=237537.1
            http://www.oracledatabase12g.com/archives/what-dbms_stats-can-not-but-analyze-can-do.html
本文原创,转载请注明出处、作者
如有错误,欢迎指正
邮箱:czmcj@163.com

0
0
分享到:
评论

相关推荐

    DBMS_STATS.GATHER_TABLE_STATS详解.pdf

    2. **对于非分区表**:同样推荐使用 `DBMS_STATS`,因为它支持并行处理、自动分析等功能,相比 `ANALYZE` 更加准确且高效。 ##### 示例 ```sql EXECUTE DBMS_STATS.GATHER_TABLE_STATS( ownname =&gt; 'OWNER', ...

    使用dbms_stats包手工收集统计信息

    在使用 dbms_stats.gather_schema_stats 过程时,如果你想要知道自从上一次分析统计数据以来,发生了多少次插入、更新和删除操作,可以使用 alter table xxx monitoring 命令,Oracle 会用 dba_tab_modifications ...

    Metalink_DBMS_STATS.doc

    传统上,有两种方法来收集这些统计信息:ANALYZE(或通过DBMS_UTILITY包)和DBMS_STATS包。然而,随着Oracle版本的发展,DBMS_STATS逐渐成为更推荐的选择,因为它提供了更准确的统计信息和并行收集统计的能力。 **...

    Oracle统计分析-dbms_stats.pdf

    Oracle 统计分析-dbms_stats.pdf Oracle 中的统计分析对于数据库的性能至关重要。dbms_stats 是 Oracle 提供的一个统计分析工具,能够良好地估计统计数据,特别是针对较大的分区表,并且能获得更好的统计结果,最终...

    DBMS_XMLDOM DBMS_XMLPARSER DBMS_XMLQUERY 文档

    Oracle数据库系统提供了强大的XML处理能力,这主要体现在其内置的几个PL/SQL包上,如DBMS_XMLDOM、DBMS_XMLPARSER和DBMS_XMLQUERY。这些包为开发者提供了处理XML文档的一整套工具,使得在数据库环境中进行XML数据的...

    ORACLE DBMS STATS ERROR

    错误提示显示在尝试运行某些与`DBMS_STATS`相关的PL/SQL语句时,如`UTLRP.SQL`脚本,会遇到以下错误: - `PL/SQL: Statement ignored` - `PLS-00302: component 'IS_STATS_FROM_UPGRADE' must be declared` - `ORA-...

    dbms_stats.docx

    ### DBMS_STATS在Oracle数据库中的应用 #### 一、DBMS_STATS概述 DBMS_STATS是Oracle提供的一款功能强大的工具包,主要用于收集表和索引的统计信息,进而帮助Oracle的Cost-Based Optimizer (CBO)生成更为高效的执行...

    oracle dbms_lob

    在实际应用中,`DBMS_LOB`包通常与SQL DML语句结合使用,以处理LOB字段。例如,可以使用`DBMS_LOB.WRITE`在INSERT或UPDATE语句中修改LOB值,或者使用`DBMS_LOB.APPEND`在已有的LOB后面添加新内容。 学习`DBMS_LOB`...

    ORACLE SYS.DBMS_REGISTRY_SYS has errors

    标题中的问题“ORACLE SYS.DBMS_REGISTRY_SYS has errors”指的是在Oracle数据库系统中,系统包BODY `SYS.DBMS_REGISTRY_SYS` 出现错误,导致了一系列的PL/SQL调用失败。这种错误通常与数据库的元数据注册功能有关,...

    Re-post: DBMS_XPLAN : Display Oracle Execution Plans

    标题“DBMS_XPLAN: 显示Oracle执行计划”是一个关于Oracle数据库系统中用于分析SQL查询执行性能的重要工具的讨论。这个工具允许用户查看SQL语句的执行计划,从而理解数据库如何处理这些语句,以及哪些操作可能影响...

    Oracle 11g收集各种统计信息(DBMS_STAT)

    在Oracle 7版本中,analyze语句被用来收集统计信息,但在Oracle 8.1.5引入DBMS_STATS后,Oracle开始推荐使用这个包,因为它提供了更高级的功能和控制。 DBMS_STATS的主要功能是分析表、索引和其他数据库对象,以...

    dbms_obfuscation_toolkit加密解密数据

    ### DBMS_OBFUSCATION_TOOLKIT:Oracle 数据库中的加密与解密工具包 DBMS_OBFUSCATION_TOOLKIT是Oracle数据库提供的一种用于数据加密解密的强大工具包,自Oracle 8i版本开始引入。它支持多种加密算法,如DES、...

    怎样禁用及回收java的授权dbms_java

    ### 如何禁用及回收Java的授权:dbms_java 授权管理详解 #### 一、引言 在Oracle数据库环境中,`dbms_java`包提供了一系列功能强大的工具,用于管理和控制Java应用程序的安全性。这对于那些在Oracle环境中部署了...

    DBMS_SQL的使用

    ### Oracle DBMS_SQL 使用详解 #### 一、概述 在Oracle数据库中,`DBMS_SQL`包是一个功能强大的工具,用于执行动态SQL语句。它提供了处理动态SQL语句的能力,使得开发人员能够灵活地构建和执行SQL语句,而不需要...

    DBMS_RANDOM.VALUE OR DBMS_RANDOM.STRING

    在Oracle数据库系统中,`DBMS_RANDOM`是一个非常实用的包,它提供了生成随机数和随机字符串的功能。这个包在各种场景下都有广泛的应用,比如在测试数据的生成、模拟随机行为或者创建伪随机数据时。我们将深入探讨`...

    PostgreSQL_DBMS_for_Windows_922_136133.exe

    支持ArcGIS10.2版本的PostgreSQL_DBMS_for_windows_922,ESRI官方原版资源。

    Analyze_Oracle_Table.rar_Table_analyze orac_analyze orac_oracle

    "orac_analyze"和"oracle_analyze_tab"可能是指Oracle中的DBMS_STATS包,这是一个PL/SQL包,提供了用于收集和管理统计信息的接口。DBMS_STATS包允许我们自定义分析的粒度,比如可以分析整个表,也可以分析表的部分...

    dbms_lock控制串行详解

    DBMS_LOCK是Oracle数据库系统中的一个内置包,用于在用户会话之间实现锁的管理,以确保并发操作的安全性和数据一致性。这篇博文深入探讨了DBMS_LOCK的功能、使用方法以及在实际应用中的重要性。 首先,我们要理解...

    DBMS_SQL.rar_dbms_oracle

    在Oracle数据库系统中,DBMS_SQL是一个非常重要的包,它提供了动态执行SQL语句的功能,这对于开发复杂的数据库应用或者需要在运行时构建SQL语句的情况非常有用。DBMS_SQL允许我们处理那些在编译时未知的SQL语句,极...

Global site tag (gtag.js) - Google Analytics