您的位置:首页 > 其它

表分析 analyze 及dbms_stats 提高执行计划准确性

2009-11-20 19:29 459 查看
之前遇到这样一个问题,有个表有3000W多条数据,并且每月都有300W左右的数据量在增加,同时这个表的数据经常需要查询更新和删除。

由于经常进行插入,删除,更新从而导致执行计划很不准,一条很简单的链接查询都要好几分钟。稍微复杂点的查询经常超时。

经过表分析后,同一条查询语句,执行计划变了不少,查询速度也提高了许多。现在将用过的几个语句抄录下来,或许对有的朋友来说用的着。

一.analyze

1、功能
a.搜集和删除索引、表盒簇的统计信息
b.验证表、索引和簇的结构
c.鉴定表、簇和行迁移行连接
d.针对analyze 的搜集和删除统计信息功能而言,oracle 推荐使用DBMS_STATS 包来搜集优化信息,DBMS_STATS可以并行的搜集

信息,可以搜集分区表的全局信息,进一步来说,按成本的优化器只会使用DBMS_STATS包所统计出来的信息。
2、使用的先决条件:必须在自己的方案中有 analyze any system 的权限

3. 实例

a. sql> Analyze table tablename compute statistics;
b. sql>Analyze index|cluster indexname estimate statistics;

c. sql>ANALYZE TABLE tablename DELETE STATISTICS;
d. sql>ANALYZE TABLE tablename VALIDATE REF UPDATE;
e. sql>ANALYZE TABLE tablename VALIDATE STRUCTURE ;

3.分析表的限制
a)不可以分析数据字典表
b)不可以分析扩展表,但可以用DBMS_STATS来实现这个目的
c)不可以分析临时表
d)不可以计算或估计下列字段类型REFs, varrays, nested tables, LOBs (LOBs are not analyzed, they are skipped), LONGs, or object types.

二.dbms_stats包

1.功能简介

dbms_stats是提高SQL执行速度的一种出色机制。通过使用dbms_stats来收集最高质量的统计数据,CBO能够正确判断执行任何SQL查询时的最快途径。dbms_stats还在不断地改进。目前,它的一些令人激动的新特性(自动样本大小和自动直方图生成)已经显著简化了Oracle专家的工作。

2.语法格式

exec dbms_stats.gather_schema_stats( -ownname => 'SCOTT', -options => 'GATHER AUTO', -estimate_percent => dbms_stats.auto_sample_size, -method_opt => 'for all columns size repeat', -
degree => 15 -
)

参数说明

options选项

使用4个预设的方法之一,这个选项能控制Oracle统计的刷新方式:

gather——重新分析整个架构(Schema)。
gather empty——只分析目前还没有统计的表。
gather stale——只重新分析修改量超过10%的表(这些修改包括插入、更新和删除)。
gather auto——重新分析当前没有统计的对象,以及统计数据过期(变脏)的对象。注意,使用gather auto类似于组合使用gather stale和gather empty。
注意,无论gather stale还是gather auto,都要求进行监视。如果你执行一个alter table xxx monitoring命令,Oracle会用dba_tab_modifications视图来跟踪发生变动的表。这样一来,你就确切地知道,自从上一次分析统计数据以来,发生了多少次插入、更新和删除操作。

estimate_percent选项
以下estimate_percent参数是一种比较新的设计,它允许Oracle的dbms_stats在收集统计数据时,自动估计要采样的一个segment的最佳百分比:
estimate_percent => dbms_stats.auto_sample_size

要验证自动统计采样的准确性,你可检视dba_tables sample_size列。一个有趣的地方是,在使用自动采样时,Oracle会为一个样本尺寸选择5到20的百分比。记住,统计数据质量越好,CBO做出的决定越好。

method_opt选项

dbms_stats的method_opt参数尤其适合在表和索引数据发生变化时刷新统计数据。method_opt参数也适合用于判断哪些列需要直方图(histograms)。

某些情况下,索引内的各个值的分布会影响CBO是使用一个索引还是执行一次全表扫描的决策。例如,假如在where子句中指定的值的数量不对称,全表扫描就显得比索引访问更经济。

如果你有一个高度倾斜的索引(某些值的行数不对称),就可创建Oracle直方图统计。但在现实世界中,出现这种情况的机率相当小。使用CBO时,最常见的错误之一就是在CBO统计中不必要地引入直方图。根据经验,只有在列值要求必须修改执行计划时,才应使用直方图。

为了智能地生成直方图,Oracle为dbms_stats准备了method_opt参数。在method_opt子句中,还有一些重要的新选项,包括skewonly,repeat和auto:
method_opt=>'for all columns size skewonly'
method_opt=>'for all columns size repeat'
method_opt=>'for all columns size auto'

skewonly选项会耗费大量处理时间,因为它要检查每个索引中的每个列的值的分布情况。

假如dbms_stat发现一个索引的各个列分布得不均匀,就会为那个索引创建直方图,帮助基于代价的SQL优化器决定是进行索引访问,还是进行全表扫描访问。例如,在一个索引中,假定有一个列在50%的行中,如清单B所示,那么为了检索这些行,全表扫描的速度会快于索引扫描。
--*************************************************************
-- SKEWONLY option—Detailed analysis
--
-- Use this method for a first-time analysis for skewed indexes
-- This runs a long time because all indexes are examined
--*************************************************************

begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size skewonly',
degree => 7
);
end;
重新分析统计数据时,使用repeat选项,重新分析任务所消耗的资源就会少一些。使用repeat选项(清单C)时,只会为现有的直方图重新分析索引,不再搜索其他直方图机会。定期重新分析统计数据时,你应该采取这种方式。
--**************************************************************
-- REPEAT OPTION - Only reanalyze histograms for indexes
-- that have histograms
--
-- Following the initial analysis, the weekly analysis
-- job will use the “repeat” option. The repeat option
-- tells dbms_stats that no indexes have changed, and
-- it will only reanalyze histograms for
-- indexes that have histograms.
--**************************************************************
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size repeat',
degree => 7
);
end;

使用alter table xxx monitoring;命令来实现Oracle表监视时,需要使用dbms_stats中的auto选项。如清单D所示,auto选项根据数据分布以及应用程序访问列的方式(例如通过监视而确定的一个列的工作量)来创建直方图。使用method_opt=>’auto’类似于在dbms_stats的option参数中使用gather auto。
begin
dbms_stats.gather_schema_stats(
ownname => 'SCOTT',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all columns size auto',
degree => 7
);
end;

3.实例说明

例如对建有分区的表JCXX_NSRSRNSXX2 进行分析 所有者‘bims’,表名‘JCXX_NSRSRNSXX2’,分区名'P_2007' 进行分析 cascade 指定为true则对索引一起分析。(默认不分析)

SQL> exec dbms_stats.gather_table_stats('bims','JCXX_NSRSRNSXX2', 'P_2007', method_opt => 'for all indexed columns', granularity => 'PARTITION', cascade=>true);

4.有时候可能出现分析后效果不明显,那么建议在分析前先将之前的分析结果删除掉,语句如下:

--删除原来分析结果
SQL> exec dbms_stats.delete_table_stats('bims','JCXX_NSRSRNSXX2', 'P_SR2_0909');

dbms_stats是提高SQL执行速度的一种出色机制。通过使用dbms_stats来收集最高质量的统计数据,CBO能够正确判断执行任何SQL查询时的最快途径。dbms_stats还在不断地改进。目前,它的一些令人激动的新特性(自动样本大小和自动直方图生成)已经显著简化了Oracle专家的工作。

对命令与工具包的一些总结
1、对于分区表,建议使用DBMS_STATS,而不是使用Analyze语句。
a) 可以并行进行,对多个用户,多个Table
b) 可以得到整个分区表的数据和单个分区的数据。
c) 可以在不同级别上Compute Statistics:单个分区,子分区,全表,所有分区
d) 可以倒出统计信息
e) 可以用户自动收集统计信息
2、DBMS_STATS的缺点
a) 不能Validate Structure
b) 不能收集CHAINED ROWS, 不能收集CLUSTER TABLE的信息,这两个仍旧需要使用Analyze语句。
c) DBMS_STATS 默认不对索引进行Analyze,因为默认Cascade是False,需要手工指定为True
3、对于oracle 9里面的External Table,Analyze不能使用,只能使用DBMS_STATS来收集信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: