Oracle数据库性能调优

一. SQL优化
1. Where中条件语句的放置顺序:
Oracle是自后向前解析,所以要把能过滤掉最大记录数的条件放在最后面。例如“主键ID=?”这样的条件。

2. select语句中不要使用*
Oracle在解析时,会把*转换成所有的列名,这个工作是通过查询数据字典完成的,这会耗费更多的时间。

3. 使用索引:
使用索引的好处:可提高查询的效率
使用索引的坏处:索引需要空间来存储,也需要花费代价来维护:每当有记录增减时,索引本身也需要被修改。所以不必要的索引反而是反应时间变慢。

使用索引需要注意的地方:
1)避免在索引列上使用NOT或函数
Not的副作用和函数相同,Oracle系统发现Not,就会停止使用索引而执行全表扫描。

2)避免在索引列上使用计算
例如:我们对sal列建立了索引
低效:select ... from dept where sal * 12 < 25000;
高效:select ... from dept where sal < 25000 / 12;
如果对索引列使用计算,Oracle将不使用索引而使用全表扫描

3)避免在索引列上使用is null或is not null
不要对可以为空的列建立索引。
如果我们对可以为空的列建立了索引,那么Oracle的索引对于该条为null的记录将不起作用:
a) 对于单列索引,如果包含null值,索引中将不存在此记录
b) 对于多列索引,如果至少有一列不为null, 则该条记录将记录在索引中,且Oracle不允许插入重复的记录。
例如,A,B两列作为索引,表中存在一条记录(123, null),Oracle将不再接受下一条记录(123, null). 但如果表中已有记录(null, null), 则Oracle允许下一条记录(null, null),因为Oracle规定null != null.
一句话概括,null值不会存储在索引中。
低效:(索引失效):select ... from dept where dept_code is not null;
高效:select ... from dept where dept_code >= 0;

4) 使用通配符%会使Oracle索引失效
低效:(索引失效):select ... from dept where dept_code like '%12345%';
高效:select ... from dept where dept_code like '12345';

5) 避免改变索引的类型:
如果dept_code是数值型
select ... from emp where empno = '123';
实际上,Oracle会转换成:select ... from emp where empno = TO_NUMBER('123'), 这样幸运的是,转换函数没有发生在索引列上,所以索引仍然有效。
但对于:emp_type是varchar2类型的时候:
select ... from emp where emp_type=123 将被换换成: select ... from emp where TO_NUMBER(emp_type)=123; 这时索引将失效,因为对于Oracle, 当字符和数值比较时,会优先将字符型转成数值型。

6)如果查询的数据量超过全表数据的30%, 那么即使使用索引也没有显著的提高

除了使用索引,我们还有其他能减少资源消耗的方法:
1. 用exist替换distinct
低效:select distinct dept_no, dept_name from dept d, emp e where d.dept_no=e.dept_no and e.sex=man;
高效:select dept_no, dept_name from dept d where exist (
select 'X' from emp e where e.dept_no=d.dept_no and e.sex=man
      );
对于"一对多"的表,如(部门表和员工表),exist效率更高,因为oracle将在子查询条件一旦满足后,立刻返回结果。

2. 用(union) union all替换or (只适用于多个索引列)
低效:select loc_id, loc_desc, region from location where loc_id=10 or region='beijing';
高效:select loc_id, loc_desc, region from location where loc_id=10 union all
select loc_id, loc_desc, region from location where region='beijing';

当loc_id和retion是联合索引的时候,如果使用or,索引将失效。

3. order by要加在索引列上,最好是主键上。
例如:dept_code是索引列
低效:select dept_code from dept order by dept_type;
高效:select dept_code from dept order by dept_code;

4. 避免使用耗费资源的操作
如果SQL中带有distinct, union, minus, intersect,则会启动SQL引擎,执行耗费资源的排序功能。

5. 使用where替代having (如果可以的话)
低效:select job, avg(sal) from emp group by job having job='aaa' and avg(sal)>100;
高效:select job, avg(sal) from emp where job='aaa' group by job having avg(sal)>100;
在执行group by之前,先用where过滤掉一部分记录。

6. 尽量避免使用子查询。
因为子查询的代价是比较昂贵的。

=========================
Oracle索引学习:
索引分类:
1. 按存储方式分类:
1) B树索引:B-tree索引是最常用的索引。其存储结构类似于书的索引。有分支和叶两种类型的存储数据块。分支块相当于书的大目录,叶块相当于索引到具体的书页。一般索引和唯一约束索引都是b-tree索引。
2) 位图索引:该索引主要为了节省空间,减少Oracle对于数据库的访问。采用位图索引一般是针对重复值太多的表字段。

2. 按功能分:
1)唯一索引:唯一索引有两个作用:一是数据约束(数据唯一),而是数据索引(索引中每一条记录对应一个唯一的rowId)
2)主关键字索引:同唯一索引
3)一般索引:一般索引不会产生数据约束的作用。

3. 按索引对象分类:
1)单列索引(表单个字段的索引)
2)多列索引(表多个字段的索引)
3)函数索引(对字段进行函数运算的索引)

索引优点:在数据量大时,查询效率更高,因为排序了
索引缺点:查询时需要排序,增加了排序开销。
当修改需求大于检索需求时,不需要建索引。

猜你喜欢

转载自doudou-001.iteye.com/blog/2253953