Oracle9i中使用DBMS_STATS.DELETE_INDEX_STATS删除索引的统计


在Oracle9i中使用DBMS_STATS.DELETE_INDEX_STATS删除索引的统计后不能立刻对执行计划产生影响

(1)在scott.dept表的dname列有索引IDX_DEPT_DNAME,但没有对其进行分析统计

CREATE INDEX SCOTT.IDX_DEPT_DNAME ON SCOTT.DEPT
(DNAME)
TABLESPACE users;


ORA9I> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL                                             
---------- ------------- ---------                                             
                                                                               

ORA9I> SET AUTOTRACE TRACEONLY EXP
ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=2 Bytes=40)             

此时,该查询没有使用IDX_DEPT_DNAME索引

(2)分析索引

ORA9I> BEGIN
  2    SYS.DBMS_STATS.GATHER_INDEX_STATS (
  3        OwnName        => 'SCOTT' ,IndName        => 'IDX_DEPT_DNAME' );
  4  END;
  5  /

PL/SQL procedure successfully completed.

ORA9I>  SET AUTOTRACE OFF
ORA9I> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL                                             
---------- ------------- ---------                                             
         0             4 15-JUN-05                                             

ORA9I> SET AUTOTRACE TRACEONLY EXP
ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (Cost=2 Card=2 Byt         
          es=40)                                                               
                                                                               
   2    1     INDEX (RANGE SCAN) OF 'IDX_DEPT_DNAME' (NON-UNIQUE) (Cos         
          t=1 Card=2)                                                          
                                                                               
此时,该查询使用IDX_DEPT_DNAME索引

(3)使用SYS.DBMS_STATS.DELETE_INDEX_STATS删除统计值


ORA9I> BEGIN
  2    SYS.DBMS_STATS.DELETE_INDEX_STATS (
  3        OwnName        => 'SCOTT'   ,IndName        => 'IDX_DEPT_DNAME');
  4  END;
  5  /

PL/SQL procedure successfully completed.

ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (Cost=2 Card=2 Byt         
          es=40)                                                               
                                                                               
   2    1     INDEX (RANGE SCAN) OF 'IDX_DEPT_DNAME' (NON-UNIQUE) (Cos         
          t=1 Card=2)                                                          
                                                                               

 

ORA9I> SET AUTOTRACE OFF
ORA9I> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL                                             
---------- ------------- ---------                                             
                                                                               

此时,统计值虽然已经没有,但查询仍然使用IDX_DEPT_DNAME索引,分析可能的原因是shard pool中的字典信息(data dictionary cache)没有更新

(4)清空shared pool

ORA9I>  ALTER SYSTEM FLUSH SHARED_POOL;

System altered.

ORA9I> SET AUTOTRACE TRACEONLY EXP
ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=2 Bytes=40)             

shared pool清空后,执行计划改变,不再使用索引


(5)使用Analyze命令删除索引统计值
ORA9I> BEGIN
  2    SYS.DBMS_STATS.GATHER_INDEX_STATS (
  3        OwnName        => 'SCOTT' ,IndName        => 'IDX_DEPT_DNAME' );
  4  END;
  5  /

PL/SQL procedure successfully completed.

ORA9I> SET AUTOTRACE OFF
ORA9I> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL                                             
---------- ------------- ---------                                             
         0             4 15-JUN-05                                             


ORA9I> SET AUTOTRACE TRACEONLY EXP
ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (Cost=2 Card=2 Byt         
          es=40)                                                               
                                                                               
   2    1     INDEX (RANGE SCAN) OF 'IDX_DEPT_DNAME' (NON-UNIQUE) (Cos         
          t=1 Card=2)                                                          
                                                                               

 

ORA9I> Analyze Index SCOTT.IDX_DEPT_DNAME
  2  Delete Statistics;

Index analyzed.

ORA9I> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------                     
   0      SELECT STATEMENT ptimizer=CHOOSE (Cost=2 Card=2 Bytes=40)           
   1    0   TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=2 Bytes=40)             

 

ORA9I> SET AUTOTRACE OFF
ORA9I> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL                                             
---------- ------------- ---------                                             
               
可见,使用Analyze删除索引统计值后,字典缓冲中的数据也被更新,执行计划立刻改变                                           

                   

(5)在10g(10.1.0.3.0 )中

CREATE INDEX SCOTT.IDX_DEPT_DNAME ON SCOTT.DEPT
(DNAME)
TABLESPACE users;

ORA10G> set autotrace off
ORA10G> select BLEVEL,DISTINCT_KEYS,LAST_ANALYZED
  2  from dba_indexes where INDEX_NAME='IDX_DEPT_DNAME';

    BLEVEL DISTINCT_KEYS LAST_ANAL
---------- ------------- ---------


ORA10G> set autotrace traceonly exp
ORA10G> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=ALL_ROWS (Cost=3 Card=1 Bytes=20)
   1    0   TABLE ACCESS (FULL) OF 'DEPT' (TABLE) (Cost=3 Card=1 Bytes
          =20)


ORA10G> BEGIN
  2    SYS.DBMS_STATS.GATHER_INDEX_STATS (
  3        OwnName        => 'SCOTT' ,IndName        => 'IDX_DEPT_DNAME' );
  4  END;
  5  /

PL/SQL procedure successfully completed.

ORA10G> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=ALL_ROWS (Cost=2 Card=1 Bytes=20)
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' (TABLE) (Cost=2 Ca
          rd=1 Bytes=20)

   2    1     INDEX (RANGE SCAN) OF 'IDX_DEPT_DNAME' (INDEX) (Cost=1 C
          ard=1)

 


ORA10G> BEGIN
  2    SYS.DBMS_STATS.DELETE_INDEX_STATS (
  3        OwnName        => 'SCOTT'   ,IndName        => 'IDX_DEPT_DNAME');
  4  END;
  5  /

PL/SQL procedure successfully completed.

ORA10G> select * from scott.dept where dname='ACCOUNTING';

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT ptimizer=ALL_ROWS (Cost=3 Card=1 Bytes=20)
   1    0   TABLE ACCESS (FULL) OF 'DEPT' (TABLE) (Cost=3 Card=1 Bytes
          =20)


可见,在Oracle10g中,已解决了上述问题,通过DBMS_STATS.DELETE_INDEX_STATS删除索引统计值后,shared pool中的数据字典信息被刷新,相关的执行计划会立即改变。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13940/viewspace-612983/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13940/viewspace-612983/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`DBMS_STATS.GATHER_TABLE_STATS` 是 Oracle 数据库一个过程(procedure),用于收集表的统计信息。它可以替代旧版的 `ANALYZE TABLE` 语句,提供更高效和更精确的统计信息收集方法。 使用 `DBMS_STATS.GATHER_TABLE_STATS` 可以收集表的各种统计信息,包括行数、块数、列的分布等。这些统计信息对于优化查询性能非常重要,因为它们可以帮助优化器生成更准确的执行计划。 以下是使用 `DBMS_STATS.GATHER_TABLE_STATS` 收集表统计信息的示例: ```sql BEGIN DBMS_STATS.GATHER_TABLE_STATS( ownname => 'schema_name', tabname => 'table_name', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE ); END; ``` 在上面的示例,`schema_name` 是表所属的模式名,`table_name` 是要收集统计信息的表名。`estimate_percent` 参数控制了采样的百分比,使用 `DBMS_STATS.AUTO_SAMPLE_SIZE` 可以自动选择合适的采样大小。`method_opt` 参数指定了统计信息收集的方法和选项,'FOR ALL COLUMNS SIZE AUTO' 表示对所有列进行统计,并自动选择合适的大小。`cascade` 参数表示是否同时收集相关索引统计信息。 需要注意的是,`DBMS_STATS.GATHER_TABLE_STATS` 还有其他可选的参数,可以根据具体需求进行设置,如 `granularity`、`degree` 等。详细的参数说明可以参考 Oracle 官方文档。 通过使用 `DBMS_STATS.GATHER_TABLE_STATS`,可以更灵活地、更高效地收集表的统计信息,并提升查询性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值