高效率Oracle SQL语句

最近在JavaEye上发现好多同志对sql的优化好像是知道的很少,最近总结了几条仅供参考,不过除少数可能要依情况而定,大多数还是相当有效的。 
【注:以下说的(低效)与(高效)都是相当来说的。】

1、Where子句中的连接顺序: 
ORACLE采用自下而上的顺序解析WHERE子句。 
根据这个原理,表之间的连接必须写在其他WHERE条件之前, 那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。

举例: 
(低效) 
select ... from table1 t1 where t1.sal > 300 and t1.jobtype = ‘0001‘ and 20 < (select count(*) from table1 t2 where t2.pno = t1.tno;

(高效) 
select ... from table1 t1 where 20 < (select count(*) from table1 t2 where t2.pno = t1.tno and t1.sal > 300 and t1.jobtype = ‘0001‘;

2、Select子句中避免使用 “ * ”: 
当你想在select子句中列出所有的column时,使用动态SQL列引用 ‘*‘ 是一个方便的方法。 
不幸的是,这是一个非常低效的方法。 
实际上,ORACLE在解析的过程中,会将 ‘*‘ 依次转换成所有的列名, 这个工作是通过查询数据字典完成的, 这意味着将耗费更多的时间。

3、减少访问数据库的次数: 
当执行每条SQL语句时,ORACLE在内部执行了许多工作: 
解析SQL语句、估算索引的利用率、绑定变量、读数据块等等。 
由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量。

举例: 
题目——我要查找编号为0001、0002学生的信息。 
(低效) 
select name,age,gender,address from t_student where id = ‘0001‘; 
select name,age,gender,address from t_student where id = ‘0002‘; 
(高效) 
select a.name,a.age,a.gender,a.address,b.name,b.age,b.gender,b.address from t_student a,t_student b where a.id = ‘0001‘ and b.id = ‘0002‘;

4、使用Decode函数来减少处理时间: 
使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。

举例: 
(低效) 
select count(*), sum(banace) from table1 where dept_id = ‘0001‘ and name like ‘anger%‘; 
select count(*), sum(banace) from table1 where dept_id = ‘0002‘ and name like ‘anger%‘; 
(高效) 
select  count(decode(dept_id,‘0001‘,‘XYZ‘,null)) count_01,count(decode(dept_id,‘0002‘,‘XYZ‘,null)) count_02, 
sum(decode(dept_id,‘0001‘,dept_id,null)) sum_01,sum(decode(dept_id,‘0002‘,dept_id,null)) sum_02 
  from table1 
  where name like ‘anger%‘;

5、整合简单,无关联的数据库访问: 
如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)

举例: 
(低效) 
select name from table1 where id = ‘0001‘; 
select name from table2 where id = ‘0001‘; 
select name from table3 where id = ‘0001‘; 
(高效) 
select t1.name, t2.name, t3.name 
    from table1 t1, table2 t2, table3 t3 
    where t1.id(+) = ‘0001‘ and t2.id(+) = ‘0001‘ and t3.id(+) = ‘0001‘ 
【注:上面例子虽然高效,但是可读性差,需要量情而定啊!】

6、删除重复记录: 
最高效的删除重复记录方法 ( 因为使用了ROWID)

举例: 
delete from table1 t1 
  where t1.rowid > (select min(t2.rowid) from table1 t2 where t1.id = t2.id);

7、尽量不要使用having子句,可以考虑用where替换。 
having只会在检索出所有记录之后才对结果集进行过滤. 这个处理需要排序,总计等操作。 
如果能通过where子句限制记录的数目,那就能减少这方面的开销。

8、尽量用表的别名: 
当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上。 
这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。

9、用exists替代in(发现好多程序员不知道这个怎么用): 
在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。 
在这种情况下,使用exists(或not exists)通常将提高查询的效率。

举例: 
(低效) 
select ... from table1 t1 where t1.id > 10 and pno in (select no from table2 where name like ‘www%‘); 
(高效) 
select ... from table1 t1 where t1.id > 10 and exists (select 1 from table2 t2 where t1.pno = t2.no and name like ‘www%‘);

10、用not exists替代not in: 
在子查询中,not in子句将执行一个内部的排序和合并。 
无论在哪种情况下,not in都是最低效的 (因为它对子查询中的表执行了一个全表遍历)。 
为了避免使用not in,我们可以把它改写成外连接(Outer Joins)或not exists。

11、用exists替换distinct: 
当提交一个包含一对多表信息的查询时,避免在select子句中使用distinct. 一般可以考虑用exists替换

举例: 
(低效) 
select distinct d.dept_no, d.dept_name from t_dept d, t_emp e where d.dept_no = e.dept_no; 
(高效) 
select d.dept_no, d.dept_name from t_dept d where exists (select 1 from t_emp where d.dept_no = e.dept_no);

exists使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.

12、用表连接替换exists: 
通常来说,采用表连接的方式比exists更有效率。

举例: 
(低效) 
select ename from emp e where exists (select 1 from dept where dept_no = e.dept_no and dept_cat = ‘W‘); 
SELECT ENAME 
(高效) 
select ename from dept d, emp e where e.dept_no = d.dept_no and dept_cat = ‘W‘;

13、避免在索引列上使用is null和is not null 
避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引。 
对于单列索引,如果列包含空值,索引中将不存在此记录; 
对于复合索引,如果每个列都为空,索引中同样不存在此记录; 
如果至少有一个列不为空,则记录存在于索引中。

举例: 
如果唯一性索引建立在表的A列和B列上, 并且表中存在一条记录的A,B值为(123,null), 
ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入), 
然而如果所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空。 
因此你可以插入1000 条具有相同键值的记录,当然它们都是空! 
因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引。

14、最好把复杂的sql,去看下它的执行计划,这样有利于你分析知道自己的sql效率如何。

上面的资料也是本人长期看资料积攒下来的,并且很多都已经在项目中,特别是大数据量时得到了体现。

时间: 2024-11-08 10:28:48

高效率Oracle SQL语句的相关文章

oracle sql语句取得本周本月本年的数据

[sql] --国内从周一到周日 国外是周日到周六  select to_char(sysdate-1,'D') from dual;--取国内的星期几 去掉减一取国外的星期-- [sql] --取本周时间内的数据  select * from table  where DTIME >=trunc(next_day(sysdate-8,1)+1) and DTIME<=trunc(next_day(sysdate-8,1)+7)+1 ;     select * from table  whe

Oracle Sql语句优化

1.最高效的删除重复记录方法 (因为使用了ROWID)   例子:  DELETE FROM  EMP E  WHERE  E.ROWID > (SELECT MIN(X.ROWID) FROM  EMP X  WHERE  X.EMP_NO = E.EMP_NO); 2.在含有子查询的 SQL 语句中 , 要特别注意减少对表的查询   例子:  SELECT TAB_NAME FROM TABLES WHERE (TAB_NAME,DB_VER) = (SELECT TAB_NAME,DB_V

获取oracle sql语句中绑定变量值的方法

在诊断 sql的性能问题时,我们有时候需要获取其绑定变量的实际值,然后将此实际值带入到sql语句当中,用原来的sql构成select语句(带where条件),实际的执行一下,看一下选择性如何. 本文就是说获取其绑定变量值的方法.本文的编写得到枯荣长老的帮助,在此表示感谢. 本文适用于与oracle 10G或者更高版本的db. alter session set nls_date_format = 'yyyy-mm-dd,hh24:mi:ss'; set linesize 400 col sql_

db2和oracle sql 语句中计算两个时间差的语法

db2 sql语句中计算两个日期相差的语法 结束日期为:2015-10-10  11:30:00 开始日期为:2015-09-09  10:40:00 (1)timestampdiff(8,char(结束时间-开始时间) )(加时分秒计算,会舍去零数)值为744小时 (2)(days(结束时间)-days(开始时间))*24 +hour(结束时间)-hour(开始时间) (不加时分秒计算)值为745小时 (3)Days(结束日期)-days(开始日期)的值为31天 (4)Day(结束日期)-da

Oracle SQL语句大全(一)

Oracle SQL语句大全  1.desc(描述) emp    描述emp这张表 2.desc    dept       部门表 3.desc salgrade      薪水等级 4.select *from table 查找表中的元素 5.dual     是系统中的一张空表 6.select *from dual  7.select sysdate from dual 取出系统时间  8.select ename,sal*12 "annul sal"(取的别名) from 

oracle sql语句

##########基本操作##########启动数据库:su - oraclesqlplus / as sysdbaSQL> startup 对scott用户解锁:SQL> conn / as sysdbaSQL> alter user scott identified by tiger account unlock; 连接到指定的数据库用户:SQL> conn scott/tiger 实现操作系统开机数据库自动open:vi /etc/oratab--------------

关于oracle sql语句查询时表名和字段名要加双引号的问题

oracle初学者一般会遇到这个问题. 用navicat可视化创建了表,可是就是不能查到! 后来发现②语句可以查询到 ①select * from user; 但是,我们如果给user加上双引号就可以查到了! ②select * from "user"; 难道oracle跟mysql等不同,查询时候一定要加双引号?那这样不是很麻烦!于是经过查找资料得出如下结论: 1.oracle表和字段是有大小写的区别.oracle默认是大写,如果我们用双引号括起来的就区分大小写,如果没有,系统会自动

oracle sql语句中使用if逻辑

l在 SQL 语句中使用IF-THEN-ELSE 逻辑 l l使用两种方法: •CASE 表达式:SQL99的语法,类似Basic,比较繁琐 •DECODE 函数:Oracle自己的语法,类似Java,比较简介 1 SQL> select ename,job, sal, case job when 'PRESIDENT' then 1.1*sal 2 2 when 'MANAGER' then 1.2*sal 3 3 when 'CLERK' then 1.3*sal 4 4 else 1.4*

长沙做网站公司解密如何编写高效率的SQL语句

如何书写高效的SQL语句 长沙做网站公司在应用开发中,书写SQL语句是最基本的工作,但我们往往在这方面侧重的是功能的实现,很容易把效率问题给忽略了,在随着系统数据的不断增加,可能有些低效的SQL语句会让客户感觉系统反映缓慢,甚至还有可能会因长时间执行不出结果而报超时或其它系统错误,所以我们要养成一个良好的编码习惯,不仅要实现其功能,而且要尽可能的提高效率. 下面内容是在网络上收集的一些比较典型实用的优化点,以及在工作中用到的典型样例,供大家参考学习. 1.注意UNion和UNion all 的区