CBO基于成本的优化器:让oracle获取所有执行计划的相关信息,通过对这些信息做计算分析,最后得出一个代价最小的执行计划作为最终执行计划。
还是前面的例子,让我们再来看看CBO的表现:
SQL> select /*+ all_rows */ * from t where id = 1; 已选择50600行。 执行计划 ---------------------------------------------------------- Plan hash value: 1601196873 -------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 47385 | 3655K| 56 (4)| 00:00:01 | |* 1 | TABLE ACCESS FULL| T | 47385 | 3655K| 56 (4)| 00:00:01 | -------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("ID"=1) Note ----- - dynamic sampling used for this statement 统计信息 ---------------------------------------------------------- 9 recursive calls 0 db block gets 3649 consistent gets 0 physical reads 0 redo size 1510200 bytes sent via SQL*Net to client 37503 bytes received via SQL*Net from client 3375 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 50600 rows processed SQL> select /*+ all_rows */ * from t where id = 99; 执行计划 ---------------------------------------------------------- Plan hash value: 4013845416 ------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 79 | 2 (0)| 00:00:01 | | 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 79 | 2 (0)| 00:00:01 | |* 2 | INDEX RANGE SCAN | IND_T | 1 | | 1 (0)| 00:00:01 | ------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("ID"=99) Note ----- - dynamic sampling used for this statement 统计信息 ---------------------------------------------------------- 7 recursive calls 0 db block gets 67 consistent gets 0 physical reads 0 redo size 473 bytes sent via SQL*Net to client 400 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processedCBO作出了正确的执行计划:id=1,全表扫描;id=99,索引扫描。
CBO优化器有两种可选的运行模式:
FIRST_ROWS(n):将结果集中的前n条记录以最快的速度反馈回来,而其他的结果并不需要同时返回。(适用于分页等)
ALL_ROWS:用最快的速度将sql执行完毕,将结果集全部返回。
OLAP(在线分析系统):就是数据仓库,用户数很小,数据量非常大,长事务的操作。
OLTP(在线事务处理系统):用户并发数都很多,但他们只对数据库做很小的操作,数据库侧重于对用户操作的快速响应。
可以看见一个OLTP数据库的默认优化器就是ALL_ROWS
SQL> conn /as sysdba 已连接。 SQL> show parameter optimizer_mode NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ optimizer_mode string ALL_ROWS
dbms_stats包:
exec dbms_stats.gather_table_stats(ownname=>'u1',tabname=>'t',cascade=>true); exec dbms_stats.gather_index_stats(ownname=>'u1',indname=>'ind_t'); exec dbms_stats.gather_schema_stats(ownname=>'u1',options=>'gather auto'); options参数选项: gather ——重新分析整个架构(Schema)。 gather empty ——只分析目前还没有统计的表。 gather stale ——只重新分析修改量超过10%的表(这些修改包括插入、更新和删除)。 gather auto ——重新分析当前没有统计的对象,以及统计数据过期(变脏)的对象。 注意,使用gather auto类似于组合使用gather stale和gather empty。