欢迎光临
我们一直在努力

ORACLE SQL性能优化系列 (十一)-数据库专栏,ORACLE

建站超值云服务器,限时71元/月

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;

 

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » ORACLE SQL性能优化系列 (十一)-数据库专栏,ORACLE
分享到: 更多 (0)

相关推荐

  • 暂无文章