Oracle SQL优化

SQL优化简介
一般在应用中,  糟糕的SQL语句是造成系统性能低下的最主要原因,例如大小写的不统一、同样的SQL语句不同的写法等。而且,随着数据量的增加,情况会变得越来越严重。(题外话:优秀的Oracle数据库优化人才,是任何公司都稀缺的)
  SQL优化又称SQL调节,其步骤一般包括:
 
SQL调节的目标
 
SQL调节包括三大目标:降低负载、均衡负载和并行化负载。
 
l降低负载:即寻找更高效的途径来完成相同的功能
如某个非大表(小于2000万行数据数据或小于2G大小的单表),常规查询需要访问的数据实践中90%情况下是不会超过20%的,此时建立合理的索引是有效的方法之一
l均衡负载:即应该把任务分时段均衡调度
如一般系统白天是访问高峰,如果此时备份任务、批处理任务或报表数据抽取任务也  在这个时段则易造成负载峰值现象,正确的做法应该是把备份任务、批处理任务和报表数据抽取任务放到晚上进行处理,或采用并行化策略
l并行化负载:即大数据量的查询访问需要使用并发策略
如在数据仓库环境中应该多使用并发策略,此举可以明显减少响应时间
 
 
SQL优化阶段
 
 
使用OEM发现顶级SQL
 
 
在OEM中,选择性能->其它监视链接->定级活动,如下图:
 
 
不要用*代替所有列名
 
 
指定仅仅需要的列名与使用*对比:
时间:359/1327=27.05%  CUP耗费: 4092121327/6413227637=63.81%
IO耗费: 29601/110117=26.88%  可见大幅降低I/O从而降低响应时间!
 
 
SQL优化技巧
使用TRUNCATE代替DELETE
  Oralce执行DELETE后会使用UNDO表空间存放被删除的信息以便恢复,如果之后用户使用ROLLBACK而不是COMMIT,则Oralce将利用该UNDO表空间中的数据进行恢复。当使用TRUNCATE时,Oracle不会将删除的数据放入UNDO表空间,因而速度要快很多。当要删除某个表中的全部数据时,应该使用TRUNCATE而不是不带WHERE条件的DELETE。语法如下:
 TRUNCATE TABLE table_name [DROP|REUSE STORAGE]
 DROP STORAGE为默认的方式,表示收回被删除的表空间
 REUSER STORAGE表示保留被删除的空间以供该表的新数据使用
 
 应用开发中,可以编写一个子程序让其动态的清除空表,以供调用。
默认PCTFREE为10,假定为5,high-water mark是一个存储段分配多少存储器的标记。
 
 
 
 
 
 
 
活用COMMIT
  PL/SQL块中,经常将几个相互联系的DML语句写在BEGIN …END,如果不影响事务的完整性,则建议在每个END前面写一个COMMIT,以达到  对DML的及时提交和  释放事务所占的资源的目的。
  COMMIT释放的资源包括:
lUNDO段上用于恢复数据的信息
l事物中DML语句获得的锁
lSGA中重做日志缓冲区中的空间
lOracle为管理相关资源(如上述资源) 而开销的内部资源
体验例子流程如下 
体验例子显示 
 
减少表的查询次数
 
1.一个逻辑单元中,将能读出的列一次性读出,且尽量存放在本地变量中,应该杜绝不要用一个读一个
 
2.在包含子查询的SQL中,要特别注意减少对表的查询次数,在代码清晰时对于能减少查询次数的应坚决减少,举例如下:
2.执行计划如下,结论是什么? 
 
以EXISTS代替DISTINCT
多表信息的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXISTS替换, EXISTS 使查询更为迅速,因为此时RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果。
 
优化前:
 
优化后:
 
使用默认值
 
使用默认之后的执行时间比为1.063/2.657=40.01%,快了一倍多!
可见在不含默认值,是null的列上没有使用索引,是全表扫描!而使用了默认值的列上使用了索引范围扫描!
 
l不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能
l任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的
l如果每列确实可能存在空值的情况,可以使用默认值的方式替代以便充分利用索引提高性能
 
使用DECODE函数减少处理步骤

 
l使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表.
lDECODE函数也可以运用于GROUP BY 和ORDER BY子句中.
l上述例子有两步相似的操作,使用DECODE后节省一半时间,如果一组相似的操作越多,节省的时间则越多,计算公式为n-1,其中n为相似操作的步骤数
 
通配符的使用技巧
 
上例中已知数据%DX_ACCOUNT_TRADE%,只有以I开头的
首位使用通配符是首位不使用通配符执行效率的:0.031/1.891=1.639%
 
l当通配符出现在LIKE后面字符串的首位时,索引将不会被使用,因此在已知某字符的情况下,LIKE查询中应尽量不要把通配符写在首位
l%代表不定长的字符,_代表定长的字符,如果在确定要通配的字符长度时,应该尽量使用_,而不是%
 
定义并执行严格的SQL编写规范
 
使用Oracle共享游标的优点是:
l降低和减少Oracle对SQL的解析数量
l动态调整内存
l提高内存的使用率
 
风格请参照前面章节中的“建议的程序风格”
  
表的连接方式 
FROM表顺序选择
  使用基于规则的优化器(CBO)时,Oracle解析器按照从右到左的顺序处理FROM子句的表明,即FROM子句中最后的表(驱动表)会最先被处理。
  当FROM子句包含多个表时,建议将记录最少的表(一般是字典表)放在最后面。当Oracle处理多个表时,一般采用排序或合并的方式连接这些表,系统首先会扫描FROM子句部分的最后一个表,并对该表的数据行进行排序;然后扫描倒数第二个表,并将从该表中取出的记录与第一个表中的记录进行匹配合并,依此类推。
如果是大于两表相关联,最好选择交叉表为驱动表,交叉表是指被其它表所引用的表。
 
 
  
 
 
RBO模式下,小表为驱动表的执行时间为大表是驱动的执行时间的:
0.078/2.253 =  2.26%!
 
驱动表的选择
 
 
此时的优化器模式为CBO,二者的执行时间仅仅相差:
0.328-0.313=0.015毫秒,二者几乎接近,这是为什么呢?我们再看二者执行计划:
 
 
我们发现,此时二者的执行计划  一模一样!这又是为什么?
驱动表的选择
驱动表(Driving Table)是指被最先访问的表,通常是以全表扫描的方式访问的。
    如果优化器是CBO,则优化器会检查SQL语句中每个表的物理大小、索引状态,然后寻找开销最小的执行路径。如果优化器是RBO,且所有连接条件都有索引对应,则驱动表是FROM子句中最后一个表。
无论如何,我们建议始终将记录小的表(如字典表)作为驱动表,则能适应CBO和RBO!
 
WHERE子句如何写
Oralce优化器的原理是采用自下而上的顺序解析WHERE子句,因此表之间的连接必须写在其他WHERE条件之前, 可过滤掉最大数量记录的条件必须写在WHERE子句的末尾 。
 
 
 
上述SQL语句的例子虽然符合优化规范的比不符合优化规范的写法仅仅快了不到0.4秒,但重要的是这是在当前单机环境、且没有任何其它数据库事务、业务很简单、连接的表仅有两个表的情况下。如果在实际的大业务量环境下,则这种优化效应将成  倍数级增长!
因此,我们建议任何时候编写SQL语句时要  使用表的别名、  对表的连接永远 写在WHERE后面的第一个位置,并对过滤条件进行估算,  按照降序的大小将这些 条件从WHERE子句最后部分往前排列
 
习题
1.SQL优化的步骤包含那几步?可以使用那几种工具或方法发现糟糕的SQL?
2.SQL调节的三大目标是什么?请举例来说明如何均衡负载。
3.一般来说,SQL优化包括三个阶段,分别是语法分析、优化和执行阶段。请问,语法分析阶段的主要任务是什么?Oracle在优化阶段优化器主要执行的任务和考虑的因素又分别包含哪些?
4.在SELECT少用*,多用具体的列名其理论依据是什么?
5.Truncate包含几种用法?画图并解释Truncate如何改变高水位线。
6.举例说明什么情况下应该尽量多用COMMIT,什么情况下不能。
7.使用DECODE合并多个相类似操作,其与减少对数据库的查询次数有关系吗?
8.应该避免那种不合适的通配符的使用方法?
9.解释什么是驱动表,应该如何选择驱动表。

10.推荐的FROM子句和WHERE子句应该如何写,并解释其原理。


充分利用索引
索引的限制
1.  索引对不等号和NOT的限制
  如果WHERE条件中出现!=或者<>,即使该列建立了索引,则该索引也不会被使用;如果不恰当的使用了NOT,则索引也不会被使用。
Oracle 10g起,在基于CBO的优化器模式下Oralce会进行自动优化,但在基于RBO(基于规则)的优化器模式下,依然保持此规则。
  
 
1.  索引对不等号和NOT的限制
   RBO模式下,执行计划如下:
    
1.  索引对不等号和NOT的限制
   RBO模式下,执行情况如下:
  
 
  此时使用变通写法的耗费为:0.407/2.187=1.60%!
1.  索引对不等号和NOT的限制
   CBO模式下,执行情况如下:
 
 
此时使用变通写法的耗费节约不到0.03秒,但依然更优,故此推荐此种变通写法,再看此时使用NOT:
1.  索引对不等号和NOT的限制
   CBO模式下,在JYJE列的索引上使用NOT:
 
为使用<>的:0.156/0.329=47.42%!为变通写法的使用0.156/0.297=52.53%!  因 此这种写法最优!
 
1.  索引对不等号和NOT的限制
   一般,WHERE条件中,如果索引列是字符列,使用NOT往往也不会使用索引:
 
结论:如果索引列是数字,则对于不等号的处理可以变更为NOT的方式或者(大于 OR 小于)的方式① ;对于确实无法不使用不等号的方式,可以使用默认值② ;如果可以建立位图索引则使用位图索引③ ;否则可以考虑使用分区等方法进行优化④ ,具体是情况而定。
2.  索引对IS NULL的限制
   一般来说,如果WHERE子句基于的列是可空的列,且其建立了索引,如果使用了IS NULL,由于NULL的列本身不包含在索引中,因此无法利用索引。
所以一般对要建立索引的列不要设置为可空,如果确实含有空值,建议使用默认值代替空值,具体参见前面章节“SQL优化技巧”部分的“使用默认值”。
 
3.  索引对函数的限制
基于索引IDX_BIGTAB_OBJECTNAME,执行情况如下:
 
 
执行计划情况如下:
 
这是因为该索引是常规b-tree索引,对该列在WHERE子句中使用了函数,则不能使用索引。因此,对在WHERE子句中经常要使用函数时,应该建立基于函数的索引,且  只有当查询语句包含该函数或者表达式时,基于函数的索引才会被调 用。详情请参见索引部分的理论讲解!
 
创建并使用函数索引:
 
  
创建并使用函数索引:
此时使用基于函数的索引效率是原来的2.782/0.188=14.78!呗!
4.  索引对不匹配数据类型的限制
先看执行情况:
 
不匹配的类型执行的时间是匹配的类型的  2.187/0.266=8.2 倍!
 
再看执行计划:
 
原因分析:
  因为ACCOUNT_TRADE表的字段YKKH是CHAR,因此在对其指定的值是数字时,Oracle虽然能隐式的执行数字和字符的转换,但不会调用其索引。而当对其指定是字符时,则不存在此问题,索引可以调用。
注意:因为数据类型的不匹配和Oracle对数据类型的隐式转换,此种类型的低效代码在任何项目中均可能因为大意而存在,因此建议开发人员和管理人员要定期抽查相应的代码,以杜绝此类低效代码!
索引类型总结
类型
,描述
b-tree索引
最常最多使用的索引,其树结构与二叉树比较类似,根据ROWID快速定位所访问的行
bitmap索引
使用位图来管理与数据行的对应关系,适用于基数比较少的列
降序索引
降序索引在叶子节点中的存储从左到右是按照从大到小排序的;一般是针对逆向排序较多的查询时才使用该类型索引
函数索引
针对要频繁对列使用函数的索引,只有当查询语句包含该函数或者表达式时,基于函数的索引才会被调用
反转索引
反转了b*tree索引码中的字节,使索引条目分配更均匀,多用于并行服务器环境下,用于减少索引的竞争
分区索引
分区表的索引,又包括本地分区索引(本地前缀分区索引和本地非前缀分区索引)和全局索引,一般建议使用本地分区索引,因其与基表具有良好的数据均衡性和可维护性
 
 
访问路径
1. 全表扫描
 全表扫描(FULL TABLE SCANS)时所有行、所有数据块均会被读到,是  效率最 低的一种,一般会在表  缺少索引、  读取大量数据、  访问小表或  高并发时发生。
 
 
2. ROWID扫描
  ROWID扫描(ROWID SCANS)是通过ROWID中数据文件和块位置访问数据行。一般作为访问索引后的第二步,如果访问的列全部包含在索引中,则不会执行ROWID扫描。
 
  作为索引访问后的第二步:
  访问的列全部在索引中不再执行ROWID扫描 
 
3. 索引扫描
  索引扫描(INDEX SCANS)包含全索引扫描(full index scan、FIS)、快速全索引扫描(fast full index scan、FFIS)、索引范围扫描(index range scan)、索引唯一扫描 (index unique scan)、索引跳跃式扫描 (index skip scan)、位图索引扫描(bitmap index scan),  其中前5种在本系列课程的索引章 节部分已经讲解了其理论和示例。位图索引示例如下:
 
3. 索引扫描
类型
方式
发生条件
 1.FULL INDEX SCANS
逐一读取索引中的所有块,由于索引中数据已按索引键排序,因此会忽略掉排序
1.ORDER BY中的列全部在该索引中时 
2.ORDER BY中列的顺序满足索引中前导列的顺序时 
3.使用GROUP BY且该子句中的列在索引中时
2.FAST FULL INDEX SCANS
只扫描索引中的数据,不会扫描表中的数据;由于索引中数据未按索引键排序,因此不能忽略掉排序
当同时满足下列条件是,Oracle用FFIS替代FIS: 
1.查询的所有列均包含在索引中 
2.索引中的列至少一个具有not null约束
3.INDEX RANGE SCANS
访问选择性数据最常用的扫描方式;按顺序的对某个索引进行扫描,返回数据是升序排列的,可以使用唯一索引和非唯一索引;如果对索引列使用ORDER BY/GROUP BY则可省略排序
1.在唯一索引上使用范围操作符(>、<、>=、<=、<>、BETWEEN) 
2.在组合索引上使用部分列进行查询,导致查出多行
4.INDEX UNIQUE SCANS
扫描唯一索引或主键,要么返回一行数据要么返回0行数据
1.当使用唯一索引时 
2.当使用主键时
5.INDEX SKIP SCANS
其实质是将索引分解成多个小的子索引来提高效率,系从9i开始引入
复合索引中前导列的取值是枚举的从而可以分拆为多个子索引,并且查询条件中不含前导列时
 
为了  加深巩固前面的知识,本处对前五种索引扫描复习总结如下:
(1).全索引扫描
逐一读取索引中的所有块,由于索引中数据已按索引键排序,因此会忽略掉排序,可能发生的情况如下:
A. ORDER BY中的列全部在某个索引中
   全部在某个索引中:
 
(1).全索引扫描
B. ORDER BY中列的顺序满足索引中前导列的顺序时
  下面分别是满足和不满足前导列顺序时:
C. 使用GROUP BY且该子句中的列在索引中时
(2).快速全索引扫描
只扫描索引中的数据,不会扫描表中的数据;由于索引中数据未按索引键排序,因此不能忽略掉排序。当同时满足下列条件时,Oracle用FFIS替代FIS或FTS:
1.查询的所有列均包含在索引中
2.索引中的列至少一个具有not null约束(10g开始的,原低版本的系统中为查询的列中不包含任何null值)
 
全部列均在索引中:
 
 
  有列不在索引中:
 
删除该索引,创建新索引,两个列均为可空:
此时即使全部列在该索引中,  也不会发生FFIS
索引范围扫描是访问选择性数据最常用的扫描方式;按顺序的对某个索引进行扫描,返回数据是升序排列的,可以使用唯一索引和非唯一索引;如果对索引列使用ORDER BY/GROUP BY则可省略排序。
下列情形中会发生索引范围扫描:
A.在唯一索引上使用范围操作符(>、<、>=、<=、<>、BETWEEN)
B.在组合索引上使用部分列进行查询,导致查出多行
示例请参考本系列课程的索引章节部分
 
(4).索引唯一扫描
  当使用主键或唯一索引时发生。  示例请参考本系列课程的索引章节部分。
(5).索引跳跃扫描
    复合索引中前导列的取值是枚举的从而可以分拆为多个子索引,并且查询条件中不含前导列时。示例如下:
create table customers as select * from sh.customers;
CREATE INDEX customers_gender_email
  ON customers (cust_gender, cust_email);
 
(5).索引跳跃扫描
 没进行表分析前:
  
 进行表分后:
   analyze table customers compute statistics;
  
 
何时需要索引
一般地,对于从表的总行中的大部分查询只查询不到10%数据(有的称为2%-4%)的表,可以考虑创建索引。一般考虑的索引的原则包括:
 
l对于经常以查询关键字为基础的表,并且该表中的数据行是均匀分布的
l以查询关键字为基础,表中的数据行随机排序
l表中包含的列数相对比较少(仅仅是相对,需要根据实际情况确定)
l表中的大多数查询都包含相对简单的WHERE子句
l表的记录数比较少的,不建议使用索引,如数据不超过1万行的表不要建立索
 
 
为索引选择列和表达式
一般遵循的原则包括:
l经常在WHERE子句中使用的列
lSQL语句中经常用于表之间连接的列
l重复性少(可选择性高)的关键字,如主键
l不宜将经常UPDATE的列作为索引列
l不宜将经常在WHERE子句中使用,但与函数或操作符相结合的列作为索引列
l对于取值较少的列,应考虑建立位图索引,而不应该采用B树索引
l如果经常访问的列上要使用函数,应使用基于函数的索引
 
本处举例说明取值较少的列使用bitmap索引和b-tree的对比分析,B-tree时:
 
 
bitmap时:
 
 
使用复合索引
  多个列联合起来组成的索引称为复合索引、或联合索引或者组合索引,往往联合索引比单个索引具有更好的性能。创建联合索引一般遵循的原则包括:
l经常在WHERE子句中使用的列且这些列之间使用AND连接
l查询条件可能包括n个列的AND关系,而大多数情况下使用m个列是(n>m),应该考虑复合索引,且n个列为前导列
l某几个列联合起来能够组成唯一索引,应坚决建立联合唯一索引
l复合索引中,建议至少一个不能为null,且如果可能尽量将只是存在null的列对其null值采用其它默认值代替
 
本处举例说明Where中包含AND时使用多个索引性能低于联合索引的示例,使用多个索引时:
 
 
 
本处举例说明Where中包含AND是使用多个索引性能低于联合索引的示例,使用复合索引时:
 
 
结论:
项目
多个索引
复合索引
复合索引是多个索引的
一、执行时间
0.281
0.11
39.15%
二、执行计划
     
1.总耗费
1658
464
27.99%
2.I/O耗费
1562
462
29.58%
3.时间
19
6
31.58%
可见,此时复合索引是多个索引的效率的  四倍以上!
监视索引的使用情况
u正确合适的索引是查询优化性能的首选
u索引是表的索引列排序后的小型化拷贝,会增加存储开销,因此会带来Insert、Update、Delete的额外开销
u一个表可以有一个索引,也可以有多个索引,往往过多的索引或不恰当的索引带来的负面性能更多
u表索引的设计初衷,往往在40%甚至更高的情况下与最终的实际使用情况不符合,此举视设计人员对业务和Oracle的理解不同而不同
u监视索引的实际使用情况,尤其在表具有多个索引的情况下,就显得尤为重要,对经常不使用的索引采用合并为复合索引或删除是优化的工作之一
示例如下:
1.创建索引
  
2.启用所以监视
  
3.执行SQL
  
 
 
4.查看索引使用情况
 
我们可以根据一个持续时间的对索引的监控结果决定如何合并及删除不恰当的索引。
5.停止监视索引


SQL*PLUS下使用AUTOTRACE
1.AUTOTRACE简介  
  AUTOTRACE是SQL*Plus的一项功能,其作用是自动跟踪SQL语句,为SQL 语句生成一个  执行计划并且提供与  该语句的处理有关的统计信息
SQL*Plus AUTOTRACE 可以用来替代 SQL Trace 使用,AUTOTRACE 的好处是不必设置跟踪文件的格式,并且它将自动为 SQL 语句显示执行计划。AUTOTRACE与执行计划的区别是AUTOTRACE 分析和执行语句;而EXPLAIN PLAN仅分析语句,而不负责执行语句。
   AUTOTRACE在SQL*PLUS下执行,使用AUTOTRACE不会产生跟踪文件。
2.配置AUTOTRACE
  (1).确保表PLAN_TABLE已经创建,如果没有则如下创建:
  
  (2).确保角色plustrace已经创建,如果没有则如下创建:
 
3.使用AUTOTRACE
 
4. AUTOTRACE设置命令
序号
命令
解释
1
SET AUTOTRACE OFF
此为默认值,即关闭Autotrace
2
SET AUTOTRACE ON
产生结果集和解释计划并列出统计
3
SET AUTOTRACE ON EXPLAIN
显示结果集和解释计划不显示统计
4
SETAUTOTRACE TRACEONLY
显示解释计划和统计,尽管执行该语句但将看不到结果集
5
SET AUTOTRACE TRACEONLY STATISTICS
只显示统计
参见每个设置的现场举例
 
5. AUTOTRACE STATISTICS含义
序号
列名
解释
1
recursive call
递归调用SQL的个数;Oracle在执行这个SQL的时候,有时候会生成很多额外的SQL语句,这个就称为递归调用
2
db block gets
从buffer cache中读取的block的数量
3
consistent gets
从buffer cache中读取的undo数据的block的数量
4
physical reads
从磁盘读取的block的数量
5
redo size
DML生成的redo的大小
6
sorts (memory)
在内存执行的排序量
7
sorts (disk)
在磁盘上执行的排序量,如果memory空间使用不足,是会使用disk的空间的
8
bytes sent via SQL*Net to client
利用sql*net传入到client的字节数;
9
bytes received via SQL*Net from client
利用sql*net传出client的字节数;
 
使用SQL调优顾问
删除掉bigtab和smalltab上的所有索引:
 
  
 
既然上述语句性能很差,那么怎么优化呢?幸运的是Oracle提供一个工具称为SQL调优顾问。从Oracle 10g起,可以使用SQL调优顾问 (SQL Tuning Advisor ,STA)来获得一个性能很差的语句的优化结果。STA的特点是简单、智能,DBA只需要调用函数就可以给出一个性能很差的语句的优化结果,从而做到有的放矢!
使用DBMS_SQLTUNE包来创建优化任务并阅读优化建议:
创建完成后验证是否完成:
 
创建完成后验证是否完成:
 
单击该条目查看优化结果
也可以通过SQL语句来查看结果,此方法是我们最喜欢的方法:
  
进行优化:
优化后在使用autotrace:
优化后在使用autotrace:
结论:
 
项目
优化前
优化后
倍数
从持久层获取consistent gets(从buffer cache中读取的undo数据的block的数量)
21688
6950
3
物理读physical reads(从磁盘读取的block的数量)
21589
6928
3
递归调用recursive call
0
1
N/A
时间(毫秒)
2070
1078
2
使用STA能快速定位性能瓶颈,从而为性能优化提供了准确的依据!
 
实时SQL监视
   实时SQL监视(real-time SQL Monitorning)是Oracle 11g的另外一个新功能,其作用是允许用户监视正在执行的SQL。默认情况下,当使用并行查询、或者当SQL执行的CPU或I/O超过5秒钟时会自动启动。
也可以使用优化提示强制使用实时SQL监视功能,如下:
 select  /*+ monitor */  count(*)
  from bigtab a, smalltab b
   where  a.object_name=b.table_name
  如果要强制不使用实时SQL监视功能,则也可以使用优化提示:
select  /*+ no_monitor */  count(*)
  from bigtab a, smalltab b
   where  a.object_name=b.table_name
 
   与实时SQL监视相关的系统视图包括:
uV$SQL_MONITOR
uV$SQL_PLAN_MONITOR
uV$ACTIVE_SESSION_HISTORY
uV$SESSION
uV$SESSION_LONGOPS
uV$SQL
uV$SQL_PLAN
对于刚刚监视的结果,可以使用DBMS包读取:
select dbms_sqltune.report_sql_monitor from dual;
 
1.实时SQL监视示例1-执行超过5秒的SQL
  
 
 在OEM中查看监视结果,选择“性能”->“其它监视链接”->“SQL Monitoring”:
 
 
 
 查看具体的监视报告(图形化):
 
单击“文本报告”,则:
使用DBMS包查看监视结果:
 
2.实时SQL监视示例2-使用优化提示强制监视
  
  
结论:
1.实时SQL监视通过OEM查看其监视报告时,具有更好的图形化的展示效果,因此更加直观
2.如果监视的SQL语句发现具有全表扫描等执行计划的特征,或者CPU时间和I/O时间比较长,则可以与SQL调优顾问接合起来,不但能获知性能瓶颈,而且能获得Oracle推荐的优化策略。
3.实践中,程序员往往不加思考的按照自己的理解和经验编写SQL,此举在90%的项目中存在,从而造成项目产品投用后很快就产生各种性能瓶颈,正确的做法应该是  在准备好足够的测试数据,并且监视每一条SQL并在开发的初始阶段即 优化之
 
 
习题
1.在对索引的限制中,关于NOT和不等于的限制在11g数据库CBO模式下还存在吗,为什么?在RBO模式下呢?
2.如果某个索引中的列具有可空属性,则Oracle执行类似 is null时不会使用索引,其原因是什么?
3.Oralce具有那三种访问路径,其中最快的两种是什么?
4.什么情况下应该使用复合索引,此时使用复合索引比使用多个单个索引具有哪些优势?
5.分别配置并使用SQL优化常用的三种工具:Autotrace、调优顾问和实时监视顾问,复习本课的举例来加深理解。

转载私塾在线【  http://sishuok.com/forum/blogPost/list/6415.html】



你可能感兴趣的:(Oracle SQL优化)