- 浏览: 164982 次
- 性别:
- 来自: 南京
-
文章分类
最新评论
Oracle:dbms_stats统计信息在9i和10g上的区别
统计信息参数设置、是否关闭自动收集、回退统计信息、统计信息迁移
==================================================================================================
大约2个月前,一位业内人士问我为什么9i CBO迁移到10g上会出现许多执行计划改变导致的性能,他当然是为了能考考我;实际上我接触过的环境大多在8i/9i下没有使用CBO优化模式,从8i/9i的RBO模式跨越到10g上较为成熟的CBO优化模式,这当中出现执行计划讹误可以说是情理之中的;而9i CBO到10上的CBO问题也不少,我首先想到的是统计信息收集上存在区别,但具体是什么区别却又说不上。那位业内人士听了我的回答,笑,笑而不语。
Oracle十分博大,博大到可以称为Oracle的世界,很多东西长期不用就会遭人淡忘;我们来复习下9i和10g上统计信息收集的一些改动。
在9i中收集统计信息时其默认的MOTHOD_OPT模式为’FOR ALL COLUMNS SIZE 1′,使用这种模式时Oracle只收集所有列上最基础的统计信息,包括了最小/大值,distinct值等信息;但是不会收集列上的直方图。对那些数据均匀分布和没有出现在SQL语句中where子句中作为条件的列来说,这样的统计信息完全足够了。然而如果列上的数据分布并不均匀就可能导致CBO的执行计划成本计算不准确,这时我们需要手动对这些列上的直方图进行统计。
10g上对dbms_stats包中默认的METHOD_OPT模式做了修正,这显然是引起9i CBO迁移到10g CBO后易发地执行计划变化的一个重要因素,也是那位业内人士所要问的题眼。
新的默认METHOD_OPT值为”FOR ALL COLUMNS SIZE AUTO”,这意味着Oracle将通过内部算法自动决定那些列上需要收集统计信息,而那些列上不需要。是否收集直方图取决于列上数据的分布情况和与对应表相关的工作负载,这种工作负载可以解释为数据库中存在某些需要参考这些列的详细信息来计算执行成本的SQL语句。
这种方式听上去十分理想,似乎Oracle可以默默无闻地为我们抓取所有急需的统计信息。
然而问题是在许多环境中Oracle没有做出是否需要收集列上直方图的正确决定。实践证明Oracle有可能收集许许多多不必要的直方图,同时又放弃了许多需要收集的直方图。
在轻量级的应用环境中这种直方图收集不当的问题造成的影响大多数时间不为人们所察觉,相反在performance critical或已经形成性能瓶颈的环境中则可能是一场不大不小的麻烦。
此外Oracle还改变了列上密度(density)信息的计算方式。该值常被Oracle用来确定谓词选择性,当突然出现额外不必要的直方图时可能造成的广泛显著地性能影响(当然好的影响也可能出现,只是概率上……)。
显然这些莫名出现的不速之客也会给共享池造成影响,library cache与row cache相关的闩可能短期内车水马龙,如果您的应用数据表上有成百上千的列那么情况可能更糟(所以说开发要遵循范式,没有规矩的最后结果往往是应用不可用,项目失败。别告诉我你的应用苟且地活着,那同样意味着项目失败)!
======================================================================================================
利用dbms_stats来收集统计信息的时候,其procedure有很多参数是有默认值的。9i的默认值是直接写死在procedure的定义中,而10g的默认值则是一组可以由用户设置的参数值,为此,10g的dbms_stats引入了两个新的procedure:get_param和set_param。
9i:
procedure gather_table_stats (ownname varchar2, tabname varchar2, partname varchar2 default null, estimate_percent number default null, block_sample boolean default FALSE, method_opt varchar2 default 'FOR ALL COLUMNS SIZE 1', degree number default null, granularity varchar2 default 'DEFAULT', cascade boolean default FALSE, stattab varchar2 default null, statid varchar2 default null, statown varchar2 default null, no_invalidate boolean default FALSE);
10g:
procedure gather_table_stats (ownname varchar2, tabname varchar2, partname varchar2 default null, estimate_percent number default to_estimate_percent_type(get_param('ESTIMATE_PERCENT')), block_sample boolean default FALSE, method_opt varchar2 default get_param('METHOD_OPT'), degree number default to_degree_type(get_param('DEGREE')), granularity varchar2 default get_param('GRANULARITY'), cascade boolean default to_cascade_type(get_param('CASCADE')), stattab varchar2 default null, statid varchar2 default null, statown varchar2 default null, no_invalidate boolean default to_no_invalidate_type(get_param('NO_INVALIDATE')), stattype varchar2 default 'DATA', force boolean default FALSE);
The DBMS_STATS.SET_PARAM can be used to set the following parameters:
CASCADE Controls whether indexes are analyzed at the same time Default: TRUE Possible Values:
* TRUE * FALSE
Note: The default value for CASCADE set by SET_PARAM is not used by export/import procedures. It is used only by gather procedures.
Example: exec DBMS_STATS.SET_PARAM(‘CASCADE’,'FALSE’);
DEGREE Degree of parallelism. Default: NULL Possible Values:
* NULL – Use the table default value specified by the DEGREE clause in the CREATE TABLE or ALTER TABLE statement. * integer – the integer will be used as degree for all objects
Example: exec DBMS_STATS.SET_PARAM(‘DEGREE’,’5′);
ESTIMATE_PERCENT Percentage of rows to estimate Default: DBMS_STATS.AUTO_SAMPLE_SIZE Possible Values:
* Valid range is [0.000001,100] * NULL – compute will be used (100%) * DBMS_STATS.AUTO_SAMPLE_SIZE – sample sizes may vary for different versions, for example, this tends to default to a smaller sample size in 10g than in 11g.
Example: exec DBMS_STATS.SET_PARAM(‘ESTIMATE_PERCENT’,'NULL’); Note: When NULL is unquoted, this sets the parameter to the value Oracle recommends. In the case of the quoted ‘NULL’, this sets the value of the parameter itself to NULL so that the above example indicates that estimate_percent=null (i.e compute) as opposed to NULL without quotes that would imply using the default for this parameter for the specific Oracle version
METHOD_OPT Used to gather column statistics Default: FOR ALL COLUMNS SIZE AUTO. Possible Values:
* FOR ALL [INDEXED | HIDDEN] COLUMNS [size_clause] * FOR COLUMNS [size clause] column|attribute [size_clause] [,column|attribute [size_clause]…] size_clause is defined as size_clause := SIZE {integer | REPEAT | AUTO | SKEWONLY} integer : Number of histogram buckets. Must be in the range [1,254]. o REPEAT : Collects histograms only on the columns that already have histograms. o AUTO : Oracle determines the columns to collect histograms based on data distribution and the workload of the columns. o SKEWONLY : Oracle determines the columns to collect histograms based on the data distribution of the columns.
Example: exec DBMS_STATS.SET_PARAM(‘METHOD_OPT’, ‘FOR ALL COLUMNS SIZE 1′);
NO_INVALIDATE Determines whether to invalidate dependent cursors or not Default: DBMS_STATS.AUTO_INVALIDATE Possible Values:
* DBMS_STATS.AUTO_INVALIDATE – Oracle decide when to invalidate dependent cursors. * TRUE – Does not invalidate the dependent cursors * FALSE – Invalidates dependent cursors
Example: exec DBMS_STATS.SET_PARAM(‘NO_INVALIDATE’,'FALSE’);
GRANULARITY Determines granularity of statistics to collect (only pertinent if the table is partitioned). Default: ‘AUTO’ Possible Values:
* ‘AUTO’ – determines the granularity based on the partitioning type * ‘ALL’ – gathers all (subpartition, partition, and global) statistics * ‘GLOBAL’ – gathers global statistics * ‘GLOBAL AND PARTITION’ – gathers the global and partition level statistics. No subpartition level statistics are gathered even if it is a composite partitioned object. * ‘PARTITION ‘- gathers partition-level statistics * ‘SUBPARTITION’ – gathers subpartition-level statistics.
Note: ‘DEFAULT’ is obsolete. This option gathers global and partition-level statistics It is currently supported, but included in the documentation for legacy reasons only. Use the ‘GLOBAL AND PARTITION’ for this functionality.
Example: exec DBMS_STATS.SET_PARAM(‘GRANULARITY’,'GLOBAL AND PARTITION’);
AUTOSTATS_TARGET This parameter is applicable only for auto statistics collection. The value of this parameter controls the objects considered for statistics collection Default: ‘AUTO’ Possible Values:
* ‘AUTO’ – Oracle decides for which objects to collect statistics * ‘ALL’ – Statistics are collected for all objects in the system * ‘ORACLE’ – Statistics are collected for all Oracle owned objects. This option restricts the list of schemas for which the automatic stats gathering job will gather statistics to a list of Oracle component system E.g. SYS, SYSMAN, WMSYS and EXFSYS in a sample database
Usage Notes
* To run this procedure, the user must have the SYSDBA or both the ANALYZE ANY DICTIONARY and ANALYZE ANY system privileges. * Note that both arguments are of type VARCHAR2 and the values need to be enclosed in quotes even when they represent numbers. * Note also the difference between NULL and ‘NULL’: o When NULL is unquoted, this sets the parameter to the value Oracle recommends. o In the case of the quoted ‘NULL’, this sets the value of the parameter to NULL.
How to Check Present Values for a Parameter
In order to check the present value for a certain parameter do:
========================================================================================================================
exec dbms_stats.set_param(‘METHOD_OPT’, ‘FOR ALL COLUMNS SIZE 1′)
select 'cascade:' as param,dbms_stats.get_param('cascade') as value from dual
union all
select 'degree:',dbms_stats.get_param('degree') from dual
union all
select 'estimate_percent:',dbms_stats.get_param('estimate_percent') from dual
union all
select 'method_opt:',dbms_stats.get_param('method_opt') from dual
union all
select 'no_invalidate:',dbms_stats.get_param('no_invalidate') from dual
union all
select 'granularity:',dbms_stats.get_param('granularity') from dual;
===========================================================================================================================
1.开启或关闭自动收集统计信息:
从Oracle Database 10g开始,通过设置初始化参数 STATISTIC_LEVEL 为 TYPICAL 或 ALL,就可以自动收集统计信息。(默认值为 TYPICAL,因此可以随即启用自动收集统计信息的功能。)
Oracle在建库后就默认创建了一个名为GATHER_STATS_JOB的定时任务,用于自动收集CBO的统计信息。
这个自动任务默认情况下在工作日晚上10:00-6:00和周末全天开启。调用DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROC收集统计信息。该过程首先检测统计信息缺失和陈旧的对象。然后确定优先级,再开始进行统计信息。
可以通过以下查询这个JOB的运行情况:
select * from Dba_Scheduler_Jobs where JOB_NAME ='GATHER_STATS_JOB'
其实同在10点运行的Job还有一个AUTO_SPACE_ADVISOR_JOB:
SQL> select JOB_NAME,LAST_START_DATE from dba_scheduler_jobs;
JOB_NAME LAST_START_DATE
------------------------------ ----------------------------------------
AUTO_SPACE_ADVISOR_JOB 04-DEC-07 10.00.00.692269 PM +08:00
GATHER_STATS_JOB 04-DEC-07 10.00.00.701152 PM +08:00
FGR$AUTOPURGE_JOB
PURGE_LOG 05-DEC-07 03.00.00.169059 AM PRC
然而这个自动化功能已经影响了很多系统的正常运行,晚上10点对于大部分生产系统也并非空闲时段。
而自动分析可能导致极为严重的闩锁竞争,进而可能导致数据库Hang或者Crash。
所以建议最好关闭这个自动统计信息收集功能:
exec DBMS_SCHEDULER.DISABLE('GATHER_STATS_JOB');
自动化永远而严重的隐患相伴随!
以上是转载盖国强的看法----http://www.eygle.com/archives/2007/12/dbms_scherduler_disable.html
我的DB一直没有关闭这个功能,而且使用的很好,暂时不打算关闭,如果那天确实影响了使用,再决定是否关闭。
关闭及开启自动搜集功能,有两种方法,分别如下:
方法一:
exec dbms_scheduler.disable('SYS.GATHER_STATS_JOB');
exec dbms_scheduler.enable('SYS.GATHER_STATS_JOB');
方法二:
alter system set "_optimizer_autostats_job"=false scope=spfile;
alter system set "_optimizer_autostats_job"=true scope=spfile;
Pfile可以直接修改初始化参数文件,重新启动数据库。
那么您为什么要这样做呢?有很多原因 — 其中一个原因是,虽然表中大部分行发生了变化,但分布情况可能没有改变,这在数据仓库中很常见。在这种情况下,您不希望再次收集统计信息,而只是希望重用原来的统计信息。另一个原因可能是您正在使用分区交换功能来刷新物化视图 (MV),并且不希望收集关于物化视图的统计信息,因为关于被交换表的统计信息也会被导入。但是,您也可以将特定的表排除在自动统计信息收集作业之外,而不需要禁止整个作业。
2.回退统计信息:
在优化器收集统计信息时可能出现的复杂情况之一是执行计划的改变 — 也就是说,原来的优化方法在收集统计信息之前一直工作良好,但是在此之后,由于新收集的统计信息产生了不良计划,导致查询突然出错。这种问题并不少见。
为避免这种灾难,统计信息的收集作业在收集新信息之前保存当前的统计信息。如果出现问题,您总可以返回到原有的统计信息,或者至少可以检查二者之间的不同之处,以便于解决问题。
例如,假设在 5 月 31 日晚上 10:00 开始运行表 REVENUE 上的统计信息收集作业,而随后查询的性能变差。Oracle 保存了原有的统计信息,您可以通过执行以下命令重新获取这些信息:
SQL> exec dbms_stats.restore_table_stats ( 'ARUP', 'REVENUE', '31-MAY-04 10.00.00.000000000 PM -04:00');
此命令恢复到 5 月 31 日晚上 10:00 为止的统计信息,时间信息是以 TIMESTAMP 数据类型提供。这样您就立即还原了由新的统计信息收集程序所作的更改。
您能够恢复的时间长度是由保留参数所决定的。要查看当前的保留参数,可使用以下查询:
SQL> select DBMS_STATS.GET_STATS_HISTORY_RETENTION from dual;
GET_STATS_HISTORY_RETENTION
---------------------------
31
在本示例中表示可以保存相当于 31 天的统计信息,但并不能予以保证。要了解统计信息所覆盖到的确切时间和日期,只需使用以下查询:
SQL> select DBMS_STATS.GET_STATS_HISTORY_AVAILABILITY from dual;
GET_STATS_HISTORY_AVAILABILITY
----------------------------------------------------------------
27-10月-08 11.14.20.357622000 下午 +08:00
该查询表明可用的最陈旧统计信息日期为 10 月 27 日下午 11:14。
您可以通过执行内建的函数将保留时间设为不同的值。例如,要将其设为 45 天,可使用:
SQL> exec DBMS_STATS.ALTER_STATS_HISTORY_RETENTION (45);
另外为什么有部分表没有被分析呢, 原因跟表DBA_TAB_MODIFICATIONS有关
3.导入导出统计信息: <script type="text/javascript"></script>
相关推荐
然而,随着Oracle版本的发展,DBMS_STATS逐渐成为更推荐的选择,因为它提供了更准确的统计信息和并行收集统计的能力。 **从ANALYZE到DBMS_STATS的迁移** Oracle 8i以来,数据库提供了两种统计信息收集方式:...
在Oracle 9i及之后版本中,`dbms_stats`包被引入,它提供了一种高效且准确的收集统计数据的方法。相比传统的`ANALYZE TABLE`命令,`dbms_stats`具有更多优势: 1. **高级统计功能**:`dbms_stats`可以更好地处理...
4. **DBMS_OUTPUT**:用于输出调试信息和结果集到客户端。 5. **DBMS_SQL**:执行动态SQL语句的强大工具。 6. **DBMS_LOCK**:实现锁管理和同步控制。 7. **DBMS_ASSERT**:提供断言机制,用于开发过程中的错误检查...
数据字典里存有用户信息、用户的权限信息、所有数据对象信息、表的约束条件、统计分析数据库的视图等。 我们不能手工修改数据字典里的信息。 很多时候,一般的ORACLE用户不知道如何有效地利用它。 dictionary...
Oracle 8i 和 9i 是 Oracle 公司在21世纪初发布的两个重要的数据库管理系统版本,它们在数据库领域有着广泛的应用。Oracle数据库是全球最受欢迎的关系型数据库管理系统之一,尤其在企业级应用中占据主导地位。以下是...
Oracle9i优化器是Oracle数据库9i版本中的一个重要组成部分,它的主要任务是在执行SQL查询时,选择出最有效的执行计划,以确保数据的快速检索和高效处理。在Oracle数据库系统中,优化器的作用不可忽视,它直接影响到...
Oracle推荐使用DBMS_STATS包收集统计信息,因为它支持并行收集、分区对象的全局统计信息收集,以及其他优化收集操作的方式。然而,对于与成本优化器无关的信息收集,如使用VALIDATE或LIST CHAINED ROWS子句以及收集...
1. **数据收集**:STATSPACK可以通过`EXECUTE DBMS_STATS.GATHER_DATABASE_STATS`等命令定期或手动收集数据库的统计信息。这些信息包括表、索引、分区、段的大小和分布,以及执行计划等。 2. **报告生成**:...
Oracle作为全球广泛使用的数据库系统之一,其9i和10g版本在当时具有重要地位,书中对这两个版本的特性进行了深入探讨。 首先,书中的“编程艺术”部分主要涵盖了PL/SQL语言的使用,包括变量、常量、条件语句、循环...
虽然STATSPACK在Oracle 10g及更高版本中被ASH(Active Session History)和AWR(Automatic Workload Repository)所取代,但其轻量级和高效的特点使其在Oracle 9i环境下仍具有重要价值。相比其他性能监控工具,...
3. **RBO的弃用**:在Oracle 10g及后续版本中,RBO不再被支持,因为CBO能更好地适应复杂查询和大型数据集。RBO基于一套预定义的规则来决定执行计划,而这些规则可能无法应对现代数据库系统的复杂性。 4. **优化模式...
它由Oracle在9i版本中引入,后来在10g及更高版本中被Automatic Workload Repository (AWR)所取代,但即便如此,STATSPACK仍然在许多环境中作为性能监控的重要手段。以下是对Oracle STATSPACK及其在高性能调整中的...
7. **性能调优**:学习SQL优化,包括使用EXPLAIN PLAN分析查询执行计划,使用DBMS_STATS收集统计信息,以及调整初始化参数。理解AWR(自动工作区管理)报告和ASH(活动会话历史)在性能监控中的作用。 8. **分布式...
为了从Oracle的成本基础优化器中获得最佳性能,重要的是要正确理解和调整相关的初始化参数,收集并维护准确的统计信息,以及利用高级特性如扩展统计信息和SQL Profile。此外,了解和利用Oracle提供的工具和功能,如...