oracle中<>执行效率,Oracle的sql执行效率优化

本文介绍如何通过调整WHERE子句、使用EXISTS和INSTR替代、避免无效操作等方法,提高ORACLE数据库查询性能。包括连接顺序优化、IN/NOTIN到EXISTS/NOT EXISTS的转换、索引技巧、函数使用和空值处理等实战建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.       WHERE子句中的连接顺序

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

如:

Select …

From operation_detail t, cargo_request r

Where t.request_sysid = r.request_sysid

And to_char(t.ingate_time,’YYYYMMDD’) >= ’20090101’

And to_char(t.ingate_time,’YYYYMMDD’) < ’20100101’

And request_sysid = 20090904001

2.       用EXISTS替代IN,NOT EXISTS替代NOT IN

Select …

From operation_detail

Where request_sysid,auto_no)

In (select request_sysid,auto_no from auto_trust_info where request_sysid = 20090904001)

改成:

Select …

From operation_detail d

Where exists (select 1 from auto_trust_info t where t.request_sysid = d.request_sysid

And t.auto_no = d.auto_no

And t.request_sysid= 20090904001)

3.       用INSTR替代LIKE

Select … from operation_detail whereinstr(auto_no , ’浙B’) > 0

4.       用EXISTS替换DISTINCT当提交一个包含一对多表信息的查询时,避免在SELECT子句中使用DISTINCT. 一般可以考虑用EXIST替换

低效:

select distinct r.request_sysid from cargo_request r,plan_auto_connection p

Where r.request_sysid = p.request_sysid

And p.end_flag = ’N’

高效:

select r.request_sysid from cargo_request r

where exists (select 1 from plan_auto_connection p

where r.request_sysid = p.request_sysid

and p.end_flag = ’N’)

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

5.       用WHERE替代HAVING

select … from test group by no having no>=9001

改为

select … from test where having no>=9001 group by no

6.       减少对表的查询

低效

select tab_name

from tables

where tab_name = ( select tab_name

from tab_columns

where version = 604)

and db_ver= ( select db_ver

from tab_columns

Where version = 604)

高效

Select tab_name

From tables

Where (tab_name,db_ver) = (select tab_name,db_ver)

From tab_columns

Where version = 604)

7.       使用DECODE函数来减少处理时间

使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。

8.在查询条件中不要对索引条件使用函数,而是在常量上使用,

如:

Query 1:                Select C1, C2, …… Cn

From   tb_A

Where handoff_date = to_date(‘2004-01-01’,’yyyy-mm-dd’)

Query 2:                Select C1, C2, …… Cn

From   tb_A

Where to_char(handoff_date,’yyyy-mm-dd’) = ‘2004-01-01’

1的效率比明显地比2好...

9.       避免在索引列上使用not、 使用计算

在索引列上使用NOT, NOT会产生在和在索引列上使用函数相同的影响.当ORACLE”碰到”NOT,他就会停止使用索引转而执行全表扫描.在索引列上使用计算,WHERE子句中,假如索引列是函数的一部分.优化器将不使用索引而使用全表扫描.

举例:

低效:

SELECT … FROM DEPT WHERE SAL * 12 > 25000;

高效:

SELECT … FROM DEPT WHERE SAL > 25000/12;

10.   避免在索引中使用任何可以为空的列,ORACLE将无法使用该索引.

对于单列索引,假如列包含空值,索引中将不存在此记录.对于复合索引,假如每个列都为空,索引中同样不存在此记录. 假如至少有一个列不为空,则记录存在于索引中.举例:假如唯一性索引建立在表的A列和B列上,并且表中存在一条记录的A,B值为(123,null) , ORACLE将不接受下一条具有相同A,B值(123,null)的记录(插入).然而假如所有的索引列都为空,ORACLE将认为整个键值为空而空不等于空.因此你可以插入1000条具有相同键值的记录,当然它们都是空!因为空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使ORACLE停用该索引.低效: (索引失效)SELECT … FROM DEPARTMENT WHERE DEPT_CODE IS NOT NULL;

高效: (索引有效) SELECT … FROM DEPARTMENT WHERE DEPT_CODE >=0;

11.   外连接 (+) 修改成 left join on形式

(+)的外连接是属于sql92标准left join on是sql99标准,left  join on不仅表的连接结构上更清晰了,而且在取字段不会进行全表扫描,例如

SELECT   *   FROM   table1,table2   , table3

Where table1.field1   =   table2.field2(+)

And   table1.field1   =   table3.field3(+);修改成:SELECT   *

FROM   (table1  LEFT   JOIN   table3   ON   table1.field1   =   table3.field3)  LEFT   JOIN   table2   ON   table3.field3   =   table2.field2;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值