ORACLE动态采样

来源:互联网 发布:c语言中文网 手机版 编辑:程序博客网 时间:2024/05/21 20:27
 

ORACLE动态采样

动态采样(Dynamic Sampling)技术的最初提出是在Oracle 9i R2,在段(表,索引,分区)没有分析的情况下,为了使CBO优化器得到足够的信息以保证做出正确的执行计划而发明的一种技术,可以把它看做分析手段的一种补充。当段对象没有统计信息时(即没有做分析),动态采样技术可以通过直接从需要分析的对象上收集数据块(采样)来获得CBO需要的统计信息。

The purpose of dynamic sampling is to improve server performance by determining more accurate selectivity and cardinality estimates.
    More accurate selectivity and cardinality estimates allow the optimizer to produce better performing plans.
    (动态采样的目的是为了通过更精确的seletivity值cardinality值来提高服务器性能,更精确的seletivity值cardinality值可以让优化器提供更好的执行计划。)

 

Estimate single-table predicate selectivities when collected statistics cannot be used or are likely to lead to significant errors in estimation.
    Estimate table cardinality for tables without statistics or for tables whose statistics are too out of date to trust.
    (当没有使用statistics统计信息或者可能导致评估错误的时候,可以提前预估出来单表的selectivities值。
      当表没有收集统计信息时,或者表的统计信息过期的时候,可以估算出表的cardinality值。)

 

示例

create table t as select object_id,object_namefrom dba_objectswhere 1=2;
-------创建表
create index index_t on t(object_id);
-------创建索引
insert into t select object_id,object_name from dba_objects;
-------插入数据
select num_rows,avg_row_len,blocks,last_analyzed from user_tableswhere table_name='T';
-------表相关信息
select blevel,leaf_blocks,distinct_keys,last_analyzed from user_indexeswhere table_name='T';

-------索引相关信息

 

从查询结果看出,表的行数,行长,占用的数据块数及最后的分析时间都是空。 索引的相关信息也没有,说明这个表和说因都没有被分析,如果此时有一条SQL 对表做查询,CBO 由于无法获取这些信息,很可能生成错误的执行计划。

 

select /*+dynamic_sampling(t 0) */ * from twhere object_id>30;

--------在Oracle 10g以后,如果一个表没有做分析,数据库将自动对它做动态采样分析,所以这里采用hint的方式将动态采样的级别设置为0,即不使用动态采样。

 

--------查看此SQL的执行计划

 

从这个执行计划,看书CBO 估计出表中满足条件的记录为4条,索引使用了索引。 我们对表做一下分析,用结果比较一下。

 

分析可以通过两中方式:

一种是analyze 命令,如:

analyze table tablename compute statistics for all indexes;

         还有一种就是通过DBMS_STATS包来分析,从9i 开始,Oracle 推荐使用DBMS_STATS包对表进行分析操作,因为DBMS_STATS 提供了更多的功能,以及灵活的操作方式。

        

SQL> exec dbms_stats.gather_table_stats(ZFTANG,'T');

PL/SQL 过程已成功完成。

 

 

select num_rows,avg_row_len,blocks,last_analyzed from user_tableswhere table_name='T';
select blevel,leaf_blocks,distinct_keys,last_analyzed from user_indexeswhere table_name='T';

-从上面的结果,可以看出DBMS_STATS.gather_table_stats已经对表和索引都做了分析。 现在我们在来看一下执行计划。

 

select * from t where object_id>30;

转载:http://blog.csdn.net/zftang/article/details/6365449

原创粉丝点击