选择显示字体大小

oracle sql性能优化系列 (十一)

oracle sql性能优化系列 (十一) 

36. 用union替换or (适用于索引列)

通常情况下, 用union替换where子句中的or将会起到较好的效果. 对索引列使用or将造成全表扫描. 注意, 以上规则只针对多个索引列有效. 如果有column没有被索引, 查询效率可能会因为你没有选择or而降低.

在下面的例子中, loc_id 和region上都建有索引.

高效:

select loc_id , loc_desc , region

from location

where loc_id = 10

union

select loc_id , loc_desc , region

from location

where region = “melbourne”

 

低效:

select loc_id , loc_desc , region

from location

where loc_id = 10 or region = “melbourne”

 

如果你坚持要用or, 那就需要返回记录最少的索引列写在最前面.

 

注意:

 

where key1 = 10 (返回最少记录)

or key2 = 20 (返回最多记录)

 

oracle 内部将以上转换为

where key1 = 10 and

((not key1 = 10) and key2 = 20)

 

译者按:

 

下面的测试数据仅供参考: (a = 1003 返回一条记录 , b = 1 返回1003条记录)

sql> select * from unionvsor /*1st test*/

2 where a = 1003 or b = 1;

1003 rows selected.

execution plan

----------------------------------------------------------

0 select statement optimizer=choose

1 0 concatenation

2 1 table access (by index rowid) of 'unionvsor'

3 2 index (range scan) of 'ub' (non-unique)

4 1 table access (by index rowid) of 'unionvsor'

5 4 index (range scan) of 'ua' (non-unique)

statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

144 consistent gets

0 physical reads

0 redo size

63749 bytes sent via sql.net to client

7751 bytes received via sql.net from client

68 sql.net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1003 rows processed

sql> select * from unionvsor /*2nd test*/

2 where b = 1 or a = 1003 ;

1003 rows selected.

execution plan

----------------------------------------------------------

0 select statement optimizer=choose

1 0 concatenation

2 1 table access (by index rowid) of 'unionvsor'

3 2 index (range scan) of 'ua' (non-unique)

4 1 table access (by index rowid) of 'unionvsor'

5 4 index (range scan) of 'ub' (non-unique)

statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

143 consistent gets

0 physical reads

0 redo size

63749 bytes sent via sql.net to client

7751 bytes received via sql.net from client

68 sql.net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

1003 rows processed

 

sql> select * from unionvsor /*3rd test*/

2 where a = 1003

3 union

4 select * from unionvsor

5 where b = 1;

1003 rows selected.

execution plan

----------------------------------------------------------

0 select statement optimizer=choose

1 0 sort (unique)

2 1 union-all

3 2 table access (by index rowid) of 'unionvsor'

4 3 index (range scan) of 'ua' (non-unique)

5 2 table access (by index rowid) of 'unionvsor'

6 5 index (range scan) of 'ub' (non-unique)

statistics

----------------------------------------------------------

0 recursive calls

0 db block gets

10 consistent gets

0 physical reads

0 redo size

63735 bytes sent via sql.net to client

7751 bytes received via sql.net from client

68 sql.net roundtrips to/from client

1 sorts (memory)

0 sorts (disk)

1003 rows processed

用union的效果可以从consistent gets和 sql.net的数据交换量的减少看出

 

37. 用in来替换or

 

下面的查询可以被更有效率的语句替换:

 

低效:

 

select….

from location

where loc_id = 10

or loc_id = 20

or loc_id = 30

 

高效

select…

from location

where loc_in in (10,20,30);

 

译者按:

这是一条简单易记的规则,但是实际的执行效果还须检验,在oracle8i下,两者的执行路径似乎是相同的. 

 

 

38. 避免在索引列上使用is null和is not null

避免在索引中使用任何可以为空的列,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;

 
 


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons