Oracle 优化策略

来源:互联网 发布:制衣厂计件工资软件 编辑:程序博客网 时间:2024/05/16 16:15

7. optimizer_mode

这个参数值的设定将影响到O r a c l e处理S Q L语句的方式。这个参数有以下四种设定值:

• FIRST_ROWSALL_ROWS 这两个设定值将使O r a c l e使用基于代价的优化方法来执行

S Q L语句(这种方法在1 3章中已经介绍过了)。在这种优化方法下, O r a c l e在执行S Q L语句的时候,将重点考虑表的大小进行优化。例如,数据库知道用户的c u s t o m e r表有10 000行纪录,而p h o n e _ t y p e表有3行纪录,那么在执行S Q L语句的时候,系统将考虑这些因素。

• RULE 这个设定值如果使用, O r a c l e将使用内部的度量系统来决定S Q L语句将如何被执

行。比如,如果一张表有索引,则O r a c l e在执行S Q L语句的时候就将使用索引进行优化。

• CHOOSE 这个值是缺省设置。当用户有必需的信息时,则告诉O r a c l e使用基于成本优化的方法。反之,则使用基于规则的方法

8. 对已存在的系统使用哪种方法进行优化

如果被使用的O r a c l e系统没有基于代价的优化方法进行优化,建议建立一个与1 3 . 2 . 5统计收集的方法中所讨论的相似的测试系统进行性能统计分析,然后改变系统所使用的优化方法。自O r a c l e5版、第6版以来,许多系统用基于规则的优化方法很好地完成了优化。实践证明,如果在没有进行测试的情况下,贸然改变系统所使用的优化方法将对系统造成灾难性的影响。

提示如果要使用基于规则的优化方法进行系统优化,可将初始化参数文件中参数o p t i m i z e r _ m o d e的值设为r u l e。在决定对系统所使用的优化方法进行改变之前,最好先建立一个测试系统对系统的性能进行评测,然后根据评测结果决定是否改变优化方法。

9. 对新系统使用哪种方法进行优化

建议对新建立的系统使用基于成本的方法进行系统的优化。基于成本的方法对表的行记数和列的列值分布极其敏感。表1 7 - 1中列出了在有2 450 000条记录的表中对l a s t _ n a m e (索引列)的值进行检索时,所使用的检索路径。

17-1 满足条件行的百分比率和检索路径

检索条件

满足条件的记录

满足条件记录的百分比

检索路径

last_name like 'J%'

187,501

7.65

全表检索

last_name like 'JO%'

87,232

3.56

利用索引检索

last_name like 'JOR%'

19,231

0.78

利用索引检索

last_name like 'JORDAN'

4,891

0.19

利用索引检索

当调节应用程序和数据库实例的的性能时,使用基于成本的优化方法,可以提高联机处理的吞吐量和基于处理S Q L语句的报表系统的灵活性。成本一词就是指O r a c l e会根据实际情况选择使用全表检索或利用索引检索方法进行查询。提示在经过内部度量系统计算之后, O r a c l e将使用一条代价最低的检索路径执行查询操作。代价是资源占用的度量。

 

 


 

174. /*+ALL_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳吞吐量,使资源消耗最小化.
例如:
SELECT /*+ALL+_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='CCBZZP';

175. /*+FIRST_ROWS*/
表明对语句块选择基于开销的优化方法,并获得最佳响应时间,使资源消耗最小化.
例如:
SELECT /*+FIRST_ROWS*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='CCBZZP';

176. /*+CHOOSE*/
表明如果数据字典中有访问表的统计信息,将基于开销的优化方法,并获得最佳的吞吐量;
表明如果数据字典中没有访问表的统计信息,将基于规则开销的优化方法;
例如:
SELECT /*+CHOOSE*/ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='CCBZZP';

177. /*+RULE*/
表明对语句块选择基于规则的优化方法.
例如:
SELECT /*+ RULE */ EMP_NO,EMP_NAM,DAT_IN FROM BSEMPMS WHERE EMP_NO='CCBZZP';

178. /*+FULL(TABLE)*/
表明对表选择全局扫描的方法.
例如:
SELECT /*+FULL(A)*/ EMP_NO,EMP_NAM FROM BSEMPMS A WHERE EMP_NO='CCBZZP';

179. /*+ROWID(TABLE)*/
提示明确表明对指定表根据ROWID进行访问.
例如:
SELECT /*+ROWID(BSEMPMS)*/ * FROM BSEMPMS WHERE ROWID>='AAAAAAAAAAAAAA'
AND EMP_NO='CCBZZP';

180. /*+CLUSTER(TABLE)*/
提示明确表明对指定表选择簇扫描的访问方法,它只对簇对象有效.
例如:
SELECT /*+CLUSTER */ BSEMPMS.EMP_NO,DPT_NO FROM BSEMPMS,BSDPTMS
WHERE DPT_NO='TEC304' AND BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

181. /*+INDEX(TABLE INDEX_NAME)*/
表明对表选择索引的扫描方法.
例如:
SELECT /*+INDEX(BSEMPMS SEX_INDEX) USE SEX_INDEX BECAUSE THERE ARE FEWMALE BSEMPMS */ FROM BSEMPMS WHERE SEX='M';

182. /*+INDEX_ASC(TABLE INDEX_NAME)*/
表明对表选择索引升序的扫描方法.
例如:
SELECT /*+INDEX_ASC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='CCBZZP';

183. /*+INDEX_COMBINE*/
为指定表选择位图访问路经,如果INDEX_COMBINE中没有提供作为参数的索引,将选择出位图索引的
布尔组合方式.
例如:
SELECT /*+INDEX_COMBINE(BSEMPMS SAL_BMI HIREDATE_BMI)*/ * FROM BSEMPMS
WHERE SAL<5000000 AND HIREDATE<SYSDATE;

184. /*+INDEX_JOIN(TABLE INDEX_NAME)*/
提示明确命令优化器使用索引作为访问路径.
例如:
SELECT /*+INDEX_JOIN(BSEMPMS SAL_HMI HIREDATE_BMI)*/ SAL,HIREDATE
FROM BSEMPMS WHERE SAL<60000;

185. /*+INDEX_DESC(TABLE INDEX_NAME)*/
表明对表选择索引降序的扫描方法.
例如:
SELECT /*+INDEX_DESC(BSEMPMS PK_BSEMPMS) */ FROM BSEMPMS WHERE DPT_NO='CCBZZP';

186. /*+INDEX_FFS(TABLE INDEX_NAME)*/
对指定的表执行快速全索引扫描,而不是全表扫描的办法.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_EMPNAM)*/ * FROM BSEMPMS WHERE DPT_NO='TEC305';

187. /*+ADD_EQUAL TABLE INDEX_NAM1,INDEX_NAM2,...*/
提示明确进行执行规划的选择,将几个单列索引的扫描合起来.
例如:
SELECT /*+INDEX_FFS(BSEMPMS IN_DPTNO,IN_EMPNO,IN_SEX)*/ * FROM BSEMPMS WHERE EMP_NO='CCBZZP' AND DPT_NO='TDC306';

188. /*+USE_CONCAT*/
对查询中的WHERE后面的OR条件进行转换为UNION ALL的组合查询.
例如:
SELECT /*+USE_CONCAT*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

189. /*+NO_EXPAND*/
对于WHERE后面的OR 或者IN-LIST的查询语句,NO_EXPAND将阻止其基于优化器对其进行扩展.
例如:
SELECT /*+NO_EXPAND*/ * FROM BSEMPMS WHERE DPT_NO='TDC506' AND SEX='M';

190. /*+NOWRITE*/
禁止对查询块的查询重写操作.

191. /*+REWRITE*/
可以将视图作为参数.

192. /*+MERGE(TABLE)*/
能够对视图的各个查询进行相应的合并.
例如:
SELECT /*+MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
AND A.SAL>V.AVG_SAL;

193. /*+NO_MERGE(TABLE)*/
对于有可合并的视图不再合并.
例如:
SELECT /*+NO_MERGE(V) */ A.EMP_NO,A.EMP_NAM,B.DPT_NO FROM BSEMPMS A (SELET DPT_NO
,AVG(SAL) AS AVG_SAL FROM BSEMPMS B GROUP BY DPT_NO) V WHERE A.DPT_NO=V.DPT_NO
AND A.SAL>V.AVG_SAL;

194. /*+ORDERED*/
根据表出现在FROM中的顺序,ORDERED使ORACLE依此顺序对其连接.
例如:
SELECT /*+ORDERED*/ A.COL1,B.COL2,C.COL3 FROM TABLE1 A,TABLE2 B,TABLE3 C
WHERE A.COL1=B.COL1 AND B.COL1=C.COL1;

195. /*+USE_NL(TABLE)*/
将指定表与嵌套的连接的行源进行连接,并把指定表作为内部表.
例如:
SELECT /*+ORDERED USE_NL(BSEMPMS)*/ BSDPTMS.DPT_NO,BSEMPMS.EMP_NO,BSEMPMS.EMP_NAM FROM BSEMPMS,BSDPTMS WHERE BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

196. /*+USE_MERGE(TABLE)*/
将指定的表与其他行源通过合并排序连接方式连接起来.
例如:
SELECT /*+USE_MERGE(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE
BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

197. /*+USE_HASH(TABLE)*/
将指定的表与其他行源通过哈希连接方式连接起来.
例如:
SELECT /*+USE_HASH(BSEMPMS,BSDPTMS)*/ * FROM BSEMPMS,BSDPTMS WHERE
BSEMPMS.DPT_NO=BSDPTMS.DPT_NO;

198. /*+DRIVING_SITE(TABLE)*/
强制与ORACLE所选择的位置不同的表进行查询执行.
例如:
SELECT /*+DRIVING_SITE(DEPT)*/ * FROM BSEMPMS,DEPT@BSDPTMS WHERE BSEMPMS.DPT_NO=DEPT.DPT_NO;

199. /*+LEADING(TABLE)*/
将指定的表作为连接次序中的首表.

200. /*+CACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) CAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

201. /*+NOCACHE(TABLE)*/
当进行全表扫描时,CACHE提示能够将表的检索块放置在缓冲区缓存中最近最少列表LRU的最近使用端
例如:
SELECT /*+FULL(BSEMPMS) NOCAHE(BSEMPMS) */ EMP_NAM FROM BSEMPMS;

202. /*+APPEND*/
直接插入到表的最后,可以提高速度.
insert /*+append*/ into test1 select * from test4 ;
203. /*+NOAPPEND*/
通过在插入语句生存期内停止并行模式来启动常规插入.

insert /*+noappend*/ into test1 select * from test4 ;

 


 

3 同优化器下的调整;
  基于成本优化器(CBO)
  (1ORACLE 8i 以上版本更多地使用成本优化器,因为它更加智能;
  (2)通过optimizer_mode=all_rows first_rows来选择CBO;通过alter session set optimizer_goal=all_rows first_rows来选择CBO;通过添加hint来选择CBO;
  (3)使用基于成本优化的一个关键是:存在表和索引的统计资料。通过analyze table 获得表的统计资料;通过analyze index获得索引的统计资料。

  (4)对于超过5个表的连接的查询,建议不要使用成本优化器,而是在SQL语句中通过添加/* + rule */提示或者通过指定的执行计划来避免可能会在20分钟以上的SQL解析时间。
  基于规则优化器(RBO)
  (1ORACLE 8i以及ORACLE的以前版本主要用(RBO),并且比较有效;
  (2)通过optimizer_mode=rule来选择RBO;通过alter session set optimizer_goal=rule来选择RBO; 通过添加/* + rule */来选择RBO;
  (3)在RBO中,from 子句的表的顺序决定表的连接顺序。From 子句的最后一个表是驱动表,这个表应该是最小的表。

  (4)限定性最强的布尔表达式放在最底层。

 

 

 

本文的目的:
1
、说一说OracleOptimizer及其相关的一些知识。
2
、回答一下为什么有时一个表的某个字段明明有索引,当观察一些SQL的执行计划时,发现确不走索引的问题。
3
、如果你对 FIRST_ROWS ALL_ROWS这两种模式有疑惑时也可以看一下这篇文章。
开始吧:
Oracle
在执行一个SQL之前,首先要分析一下语句的执行计划,然后再按执行计划去执行。分析语句的执行计划的工作是由优化器(Optimizer)来完成的。不同的情况,一条SQL可能有多种执行计划,但在某一时点,一定只有一种执行计划是最优的,花费时间是最少的。相信你一定会用pl/sql DeveloperToad等工具去看一个语句的执行计划,不过你可能对RuleChooseFirst rowsAll rows这几项有疑问,因为我当初也是这样的,那时我也疑惑为什么选了以上的不同的项,执行计划就变了
?
1
、优化器的优化方式

Oracle
的优化器共有两种的优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CBO)
A
RBO方式:优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则。比如我们常见的,当一个where子句中的一列有索引时去走索引。
B
CBO方式:依词义可知,它是看语句的代价(Cost),这里的代价主要指Cpu和内存。优化器在判断是否用这种方式时,主要参照的是表及索引的统计信息。统计信息给出表的大小 、有少行、每行的长度等信息。这些统计信息起初在库内是没有的,是你在做analyze后才出现的,很多的时侯过期统计信息会令优化器做出一个错误的执行计划,因些我们应及时更新这些信息。在Oracle8及以后的版本,Oracle列推荐用CBO的方式。
我们要明了,不一定走索引就是优的,比如一个表只有两行数据,一次IO就可以完成全表的检索,而此时走索引时则需要两次IO,这时对这个表做全表扫描(full table scan)是最好的。
2
、优化器的优化模式(Optermizer Mode)
优化模式包括Rule,Choose,First rows,All rows这四种方式,也就是我们以上所提及的。如下我解释一下:

Rule:
不用多说,即走基于规则的方式。
Choolse:
这是我们应观注的,默认的情况下Oracle用的便是这种方式。指的是当一个表或索引有统计信息,则走CBO的方式,如果表或索引没统计信息,表又不是特别的小,而且相应的列有索引时,那么就走索引,RBO的方式。
First Rows:
它与Choose方式是类似的,所不同的是当一个表有统计信息时,它将是以最快的方式返回查询的最先的几行,从总体上减少了响应时间。
All Rows:
也就是我们所说的Cost的方式,当一个表有统计信息时,它将以最快的方式返回表的所有的行,从总体上提高查询的吞吐量。没有统计信息则走基于规则的方式。
3
、如何设定选用哪种优化模式
A
Instance级别
我们可以通过在init<SID>.ora文件中设定OPTIMIZER_MODE=RULEOPTIMIZER_MODE=CHOOSEOPTIMIZER_MODE=FIRST_ROWSOPTIMIZER_MODE=ALL_ROWS去选用3所提的四种方式,如果你没设定OPTIMIZER_MODE参数则默认用的是Choose这种方式。
B
Sessions级别
通过SQL> ALTER SESSION SET OPTIMIZER_MODE=<Mode>;来设定。
C
、语句级别
这些需要用到Hint,比如:
SQL> SELECT /*+ RULE */ a.userid,
2     b.name,
3     b.depart_name
4      FROM tf_f_yhda a,
5                tf_f_depart b
6     WHERE a.userid=b.userid;
4
、为什么有时一个表的某个字段明明有索引,当观察一些语的执行计划确不走索引呢?如何解决呢?

A
、不走索引大体有以下几个原因
♀你在Instance级别所用的是all_rows的方式
♀你的表的统计信息(最可能的原因)
♀你的表很小,上文提到过的,Oracle的优化器认为不值得走索引。

B
、解决方法
♀可以修改init<SID>.ora中的OPTIMIZER_MODE这个参数,把它改为RuleChoose,重起数据库。也可以使用4中所提的Hint.
♀删除统计信息

   SQL>analyze table table_name delete statistics;
♀表小不走索引是对的,不用调的。
5
、其它相关
A
、如何看一个表或索引是否是统计信息
SQL>SELECT * FROM user_tables
  2   WHERE table_name=<table_name>
  3 AND num_rows is not null;
SQL>SELECT * FROM user_indexes
  2   WHERE table_name=<table_name>
  3     AND num_rows is not null;
b
、如果我们先用CBO的方式,我们应及时去更新表和索引的统计信息,以免生形不切合实际的执行计划。
SQL> ANALYZE TABLE table_name COMPUTE STATISTICS;
SQL> ANALYZE INDEX index_name ESTIMATE STATISTICS;
具体的ANALYZE语句请参照Oracle8i/9i refrence文档。

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 6s不能用电信卡怎么办 iphone6电信卡无服务怎么办 魅族手机电信卡怎么办 小米手机读不出sim卡怎么办 魅蓝note6耗电快怎么办 oppo手机下载密码忘了怎么办 华为v9玩飞车卡怎么办 苹果7耳机转换器不支持怎么办 华为mate10耳机声音小怎么办 200打一年到期了怎么办 手机欠费变成2g怎么办 手机4g网用不了怎么办 手机玩王者荣耀卡怎么办 华为隐私空间密码忘记了怎么办 华为手机王者太卡怎么办 华为手机太卡怎么办呢 华为手机5x太卡!怎么办 华为手机玩游戏时太卡了怎么办? 买到华为翻新机怎么办 华为畅享8声音小怎么办 华为5a安全模式怎么办 手机跳屏怎么办金立 苹果手机触控不灵敏怎么办 华为mate8手机声音小怎么办 华为mate9相机无法对焦怎么办 新疆外地电信卡信号差怎么办 华为手机搜索不到wifi怎么办 华为浏览器恢复只有一个页面怎么办 华为手机触摸屏没反应怎么办 快递不给送上楼怎么办 华为荣耀手机声音小怎么办 华为手机来电铃声小怎么办 s弯出来时老压线怎么办 苹果7p手机弯了怎么办 小米手机摔弯了怎么办 华为畅享5没声音怎么办 掌阅语音闪退怎么办 华为mate开屏成排线怎么办 华为mate8电池坏了怎么办 8plus拍照不清晰怎么办 荣耀手环3丢了怎么办