现在的位置: 首页 > 综合 > 正文

关于dbms_stats和Analyze的比较分析

2013年07月31日 ⁄ 综合 ⁄ 共 3880字 ⁄ 字号 评论关闭

转自Itpub

对于上面这个问题,用Analyze就足够解决问题,就不用劳驾dbms 包了。
  
实际上,倒是DBMS包的问题比Analyze更多,如果你实际用过的话。而且,对于非分区表,我从来没有碰到过ANALYZE出现问题的情况,如果你碰到,可以举例说明。
  
对于分区表,DBMS包问题也很多。New Featture总是有代价。 
Analyze本来就是为CBO而设计的。在RBO年代里面,Analyze只是用来Validate Structure的。Analyze的主要作用,就是提供对CBO的技术支持。
  
不过对于Analyze,Oracle已经不再增强,基本上趋向于让用户使用DBMS包,这个倒是正确的。 
SQL> analyze table employee compute statistics;
  
表已分析。
  
SQL> set autotrace on
SQL> select count(*) from employee ;
  
COUNT(*)
----------
299999
  
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1)
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP INDEX (FAST FULL SCAN) OF 'IDX_BMP_EMP_SEX'
  
Statistics
----------------------------------------------------------
153 recursive calls
0 db block gets
96 consistent gets
11 physical reads
0 redo size
370 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
  
SQL> analyze table employee delete statistics;
  
表已分析。
  
SQL> select count(*) from employee;
  
COUNT(*)
----------
299999
  
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (AGGREGATE)
2 1 TABLE ACCESS (FULL) OF 'EMPLOYEE'
  
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
5418 consistent gets
3144 physical reads
0 redo size
370 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
  
SQL> analyze table empployee ESTIMATE statistics;
analyze table empployee ESTIMATE statistics
*
ERROR 位于第 1 行:
ORA-00942: 表或视图不存在
  
SQL> analyze table employee ESTIMATE statistics;
  
表已分析。
  
SQL> select count(*) from employee;
  
COUNT(*)
----------
299999
  
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=7 Card=1)
1 0 SORT (AGGREGATE)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP INDEX (FAST FULL SCAN) OF 'IDX_BMP_EMP_SEX'
  
Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
12 consistent gets
8 physical reads
0 redo size
370 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
  
SQL> analyze table employee delete statistics;
  
表已分析。
  
SQL> exec DBMS_STATS.GATHER_table_STATS(ownname => user,tabname => 'employee', method_opt => 'for all indexed columns size 1');
  
PL/SQL 过程已成功完成。
  
SQL> select count(*) from employee;
  
COUNT(*)
----------
299999
  
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1)
1 0 SORT (AGGREGATE)
2 1 INDEX (FAST FULL SCAN) OF 'EMPLOYEE_PK' (UNIQUE) (Cost=4
Card=299999)
  
Statistics
----------------------------------------------------------
14 recursive calls
0 db block gets
680 consistent gets
670 physical reads
0 redo size
370 bytes sent via SQL*Net to client
425 bytes received via SQL*Net from client
2 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
1 rows processed
  
SQL> spool off
[/quote] 

从Bity的例子里面,实际上我们看到,DBMS_STATS包,反而让优化器选择了一个更加糟糕的路径:
原来的BITMAP FULL SCAN,原来的成本是11个Block的物理读取,96个Block的逻辑读取。
  

对于Cost,其实Oracle也是比较矛盾的。
Oracle  Open World里面,有一个Paper专门就CBO进行了详细分析,讨论了CBO的Cost的计算方式。具体文件名字等找到了我发上来。
  
对于DBMS_STATS和Analyze,我的体会是,
一般对于常规的使用(不考虑分区表,外部表等特性),使用Analyze可以帮助我们得到我们需要的数据,让Oracle 够好的工作。
  
但是对于使用CBO的产品数据库,由于往往有很多的表,索引之类的,我们一般会选择DBMS_STATS.GATHER_SCHEMA_STATS,以利用Oracle的并行,以及自动分析整个Schema的对象,如果我们用ANalyze的话,往往需要写很多的Analyze语句,而且我们如果增加了对象,新增加对象需要修改我们的Cron,比较麻烦。
但是用DBMS_STATS包收集统计信息之后,我们看到,
Oracle的选择路径编成了PK INDEX FAST FULL SCAN,对应的成本是:
670个Block的物理读取,680个Block的逻辑读取。
  
显然,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来收集信息。

 

抱歉!评论已关闭.