racle优化器用来确定提交给系统的所有查询的最佳执行方式。
(早期)基于规则的优化器(RBO)
alter session set optimizer_mode=true;
 该命令可以用来推翻初始化参数optimizer_mode的系统范围内的设置,不过只是对特定会话而言。
基于成本的优化器(CBO)
CBO基于数据的统计信息来做出决定
在Oracle 10g中,optimizer_mode参数的有效值仅是first_rows_n、first_rows和all_rows。
 alter session set optimizer_mode=FIRST_ROWS_100;
帮助CBO作出更好决定的三种基本途径:生成更好的统计量、使用存储大纲或使用提示。
SQL跟踪:
 alter session set sql_trace = true;
exec sys.dbms_session.set_sql_trace_in_session(sid, serial#, true);
exec sys.dbms_session.set_sql_trace_in_session(sid, serial#, flase);
在启动会话跟踪前,执行以下命令加上标识符,方便寻找trace文件:
 alter session set tracefile_identifier='scotts_traccec';
阅读trace文件:
 tkprof  ora76492.trc  trace_output.txt
Statspack报表:
 $ORACLE_HOME/rdbms/admin/spreport
统计量:
 1)表的统计量(行数、块数、平均行长度)
 2)列的统计量(不同值的个数、NULL的个数、数据分布情况或柱状图)
 3)索引统计量(块数、索引高度、集群因素)
 4)系统性能统计量
收集统计量的两种方法:
analyze命令:
 analyze table emp compute statistics;
analyze table emp estimate statistics sample 20 percent;
analyze table emp estimate statistics sample 1000 rows;
dbms_stats包是CBO计算统计量的首选。在将来的版本中,dbms_stats包将是计算统计量的惟一方法。
自动收集统计量的工作称为gather_stats_job,可以在DBA_SCHEDULER_JOBS视图中看到。
访问路径:
 1)全表扫描
 2)索引扫描
 3)索引范围扫描
 4)rowid查找
 5)索引跳扫
 6)快速全索引扫描
 7)索引合并
合并:
 1.Cartesian合并(Cartesian Join):两张表均做全表扫描
 2.嵌套循环合并(Nested Loop Join):外表做全表扫描
 3.排序归并合并(Sort Merge Joins):两张表进行排序
 4.散列合并(Hash Join):小表进行散列函数,大表进行相同的散列函数和小表进行匹配
 5.外部合并(Outer Join)
优化器提示:
 注解必须紧跟在select、update、merge、insert或delete关键字后面。
select empid,
ename /*+ index(e emp_pk) */
from emp e
where empid in(1001, 1002);
访问路径提示:
 /*+ FULL(表名)*/                      全表扫描
 /*+ INDEX(表名)*/                     特定索引扫描
 /*+ NO_INDEX(表名)*/                  不使用索引
 /*+ INDEX_ASC(表名)*/                 在升序模式使用索引
 /*+ INDEX_DESC(表名)*/                在降序模式使用索引
 /*+ INDEX_JOIN*/                      索引合并
 /*+ INDEX_FFS(表名)*/                 索引快速全扫描
 /*+ NO_INDEX_FFS*/                    不使用索引快速全扫描
 /*+ INDEX_SS(表名)*/                  索引跳扫
 /*+ INDEX_SS_ASC(表名)*/              在升序模式使用索引跳扫
 /*+ INDEX_SS_DESC(表名)*/             在降序模式使用索引跳扫
 /*+ NO_INDEX_SS(表名)*/               不使用索引跳扫
合并提示:
 /*+ USE_NL(表名A  表名B)*/                              使用嵌套循环合并的方法
 /*+ NO_USE_NL(表名A  表名B)*/                           不使用嵌套循环合并的方法
 /*+ USE_NL_WITH_INDEX(表名A  表名B)*/                   使用带索引的嵌套循环合并的方法
 /*+ USE_MERGE(表名A  表名B)*/                           使用排序归并合并的方法
 /*+ NO_USE_MERGE (表名A  表名B)*/                       不使用排序归并合并的方法
 /*+ USE_HASH(表名A  表名B)*/                            使用散列合并的方法
 /*+ NO_USE_HASH (表名A  表名B)*/                        不使用散列合并的方法
并行提示:
 /*+ PARALLEL(4)*/             使用并行
 /*+ NO_PARALLEL*/             不使用并行
 /*+ PARALLEL_INDEX(4)*/       使用并行化索引范围扫描
 /*+ NO_PARALLEL_INDEX*/       不使用并行化索引范围扫描
杂项提示:
 /*+ APPEND*/                       启动直接路径插入模式,以使数据插入表末端
 /*+ NOAPPEND*/                     不启动直接路径插入模式
 /*+ CACHE(表名)*/                  将查询访问的数据块放置在LRU列表最近使用的一端
 /*+ NOCACHE(表名)*/                将查询访问的数据块放置在LRU列表最早使用的一端
 /*+ PUSH_SUBQ*/                    在尽可能最早的时间计算子查询
 /*+ NO_PUSH_SUBQ*/                 在尽可能最晚的时间计算子查询
 /*+ DRIVING_SITE*/                 使分布式查询中另一个数据库成为该查询的驱动者
explain plan命令:
 explain plan set statement_id='emp_query_1' for select * from emp where empno=1005;
显示explain plan的输出:
 $ORACLE_HOME/rdbms/admin/utlxpls.sql          显示串行查询的计划结果
 $ORACLE_HOME/rdbms/admin/utlxplp.sql          显示并行查询的计划结果
dbms_xplan包:
 1)explain plan for select * from emp;
 select * from table(DBMS_XPLAN.DISPLAY);
2)select * from emp where empno=1001;
select * from table(DBMS_XPLAN.DISPLAY_CURSOR);
3)select * from table(DBMS_XPLAN.DISPLAY_AWR('AWR中的sql_id','plan_hash_value','database_id','详细等级'));
Oracle将大纲存储在表OL$、OL$HINTS和OL$NODES中,可以通过USER_OUTLINES和USER_OUTLINE_HINTS数据字典视图访问到。
创建大纲:
 1)create or replace outline emp_outline
 for gategory appl_X_outlines
on select empno, ename from emp where empno in(1001, 1002);
2)alter session set create_stored_outlines=appl_X_outlines;
select empno, ename from emp where empno in(1001, 1002);
alter session set create_stored_outlines=FALSE;
改变目录:
 alter outline emp_outline change category to appl_ZZ_outln;
重命名:
 alter outline emp_outline rename to hr_outline;
删除:
 drop outline hr_outline;