研讨linux下C/C++,GTK,Shell,Oracle

(原创)Oracle中SQL语句的十大优化

上一篇 / 下一篇  2008-04-21 17:36:28 / 个人分类:Oracle

a9BL6fU"k$J0      在开发后台程序中,怎么样优化你的SQL语句使得你的后台程序能达到高效的目的,当然通过搜索这类相关文章有很多很多,这里本人写的是通过项目中总结出的十大主要SQL性能优化,希望在开发中能给大家一定的参考。

ej-]?;{{(ad1T0Linux宝库a{H6?o.lpW

以下的实例中使用3个表 (TABLE) A(R1,R2,R3,R4,R5,C1,C2,B2) B(R1,B1,B2) C(R1,C1,C2,B2),括号中即为表中的字段 

onxT:zE)G6M0

BSF+r9n0一、使用特定表中的索引Linux宝库,O"X q _g2UC
    有时候一个表中的数据量很大时候,索引是非常非常的重要,何为索引?我来举个例子,你一听就能明白,比如:你想搜索我的电脑中一个名字为FILE.TXT文件,如果不知道该文件所在的目录(没有创建索引)情况下,基本上要扫描我的电脑中的所有盘符里的文件,如果你的硬盘中的有很多文件(相当一个表中有很多的数据),基本上是一个全盘扫描的过程,这时如果你告诉搜索,你的文件就在D盘的TEST目录下,这样来搜索速度将会大大的提高,给文件定位就相当一个索引。
}4B2b/|s1a_ oy0    好了,知道索引是干什么之后,下面来看看怎么走正确的索引,才能达到最高效。假如A表中有两个索引IDX_R1 INDEX(R1,R2,R4,R5),IDX_R3 INDEX(R1,R3,R4,R5) 现在需要做这样的操作,显示表中的条件值是R1 = 1,R3 = 3,R4 =4的所有内容。通常我们会写出下面的查询语句。
.l:v;F@hzp0    select * from A where R1 =1 and R3 =3 and R4;
sk!h+?I"I6?B+Z0按道理它走的索引是IDX_R3,有时候默认走的索引并不是你想象中的那样,特别是多表关联的情况下。所以我们进行指定一下索引,按我们真正想要的走的索引:Linux宝库:|;j%E1d,{%{$y
   select /*+ index(R1,IDX_R3) */* from A where R1 =1 and R3 =3 and R4;Linux宝库~'~:a gq%C#K.r5v

Linux宝库9r$SO$G }`j)a

二、在检索数据的时候两个表的关联查询效率低于使用EXISTS子句。
)cS P1T1i5d.t;KBr0   SELECT  B.R1,B.B1,B.B2 FROM A,B WHERE A.R1 = B.R1;
-F-gf_1IHD0   优化为:
z}(Y| M0   SELECT  B.R1,B.B1,B.B2 FROM B WHERE EXISTS(SELECT 1 FROM A WHERE A.R1 = B.R1);Linux宝库)]wd5G-p Qls8M
   如果你在WINDOWS的ORACLE的平台可以使用PL/SQL中的执行计划(EXPLAIN PLAN),看一下相应的执行时间进行验证。

C2@&df*n0

YTv;T BYg%Q"d2X0三、ORACLE的解析器是由右向左进行解析,所以在检索两个或以上表相关联的数据的时候,将数据量小的表放到最后让解析器优先解析。此方法在两个表的数据相差很大的情况下,会有点效果。

8EbA u3o0

B\Jb.F S-G+}[0四、 使用EXISTS代替IN子句,同理用NOT EXISTS 代替NOT IN

|:G2N([ H0Linux宝库aqM*En

因为使用IN子句作为一个查询条件后,ORACLE会将IN子句的数据先搜索出来以后,等结果集返回以后才作为一个条件值。而EXISTS语句是WHERE语句之前的数据优先检索完后在去检索EXISTS子句的内容。Linux宝库7TAj0t-BWL/KB

j-C6w1[o$E0五、如果有子句比较的情况下,将此比较语句放到WHERE后作为第一个条件。
_J'R)ElAae6y0_0如:

G S2z3yMyX!]0Linux宝库+Jx*k1byW2xp

SELECT A.R2 FROM A WHERE B.B2 = 3 AND 2< SELECT COUNT(1) FROM B WHERE B.R1 = A.R1;  //效率较低

;m!r!tM`0Linux宝库&S H[[x0@L

SELECT A.R2 FROM A WHERE 2< SELECT COUNT(1) FROM B WHERE B.R1 = A.R1 AND B.B2 = 3;  //效率较高Linux宝库B*c._;OJDl\'U |

"YOM2nEv9A0六、在写存储过程的时候,无论是执行UPDATE,还是执行INSERT,应该尽快的COMMIT。

1?(CjGV"k.D\0Linux宝库)gO;c;IX{L+K

七、在执行数据检索的过程中近可能少的访问同一个表。Linux宝库'KVs,yf!} ^

r7ny8xW0在写存储过程的时候,有时候因为条件值不一样,通常需要多次的去访问同一个表,这个时候可以考虑一个使用DECODE函数来代替多个条件。Linux宝库,s5H3I/n3a@ GWpd

Linux宝库&Jz-M0m Y6H|:g V w

//1
pGM I`]0SELECT SUM(Nvl(C2,0)) FROM C WHERE R1 = 12 AND C1 = 22 ;
}p!D@/k"R _D5V0//2
2x7@ _!M"c0SELECT SUM(Nvl(C2,0)) FROM C WHERE R1 = 12 AND C1 = 33 ;Linux宝库U8]u,p5Fn6\E

{;p;Q|@,_Y0优化方法:
$ss%TNa0SELECT SUM(DECODE(C1,22,C2,33,C2,0) FROM C WHERE R1 =12 AND C1 IN(22,33);Linux宝库!d)h~X@xz t;c

'SJzg1x8Cc,EPs0八、在写条件的时候尽量在条件值的左边使用函数。
kj PA] f0如:

[5[ y*D7` _rO0Linux宝库Q#d jN1~9Yk,pL U

SELECT * FROM A WHERE TO_CHAR(R5,'YYYYMM') = '200804'Linux宝库[6L{,sr'g [2H

Linux宝库 gg7x#_}&u?5P

应该使用Linux宝库V-A ~1r4j

9Kp@ ]^0SELECT * FROM A WHERE R5 = TO_DATE('200804','YYYYMM');代替Linux宝库G q"g`#@Uz

Linux宝库,u,RHJ L)u"?J


OFz6W!o-\0九、UPDATE语句写法提高效率。Linux宝库c#f`Hr N6v

0V {;]z ES0UPDATE ALinux宝库@9mUgDa@4F
SET C2 = (SELECT MAX(C2) FROM C),
5e*w0o(F#c)]#q0    B2 = (SELECT MAX(B2) FROM C)
ex#S@ ^2hw0WHERE R1 = 1000;
hA%PCKo0高效:Linux宝库:Z;r;aw"pq}*f
UPDATE A
)vL/_CfG0SET (C2, B2)Linux宝库Oj5Zdn
= (SELECT MAX(C2) , MAX(B2)
PJ*Or7p+d(mc/EQ0FROM C)Linux宝库`n"R zO-~E Mp
WHERE R1 = 1000;Linux宝库)YAx+BeD`L

C rw V.J0Linux宝库0a J2_2{!}o]
十、用EXISTS替换DISTINCT.Linux宝库#D2N z[;vx

Linux宝库 b3Rkm2~d(I

例如:Linux宝库'i@Mn9t&L?{
//低效:
3dER d Dv Xv0SELECT DISTINCT C.R1,C.B2
~1hLPz:KHW0FROM A,C
o3M _S@vnJU0WHERE A.R1 = C.R1 ;Linux宝库.\ t)H)|-O`5qaqWI

Linux宝库M^&k/\Xk6f^Z&|q[Gb

//高效:Linux宝库g G d#TF\$ly8i eV
SELECT C.R1,C.B2Linux宝库)DU,e F4Wqe
FROM C
2Ap"q wn,ST,w4H0WHERE EXISTS ( SELECT ‘X’
K LDaG"k0FROM ALinux宝库!Ov"QF&R?Xq)f*B
WHERE A.R1 = C.R1);Linux宝库 BY2S}:a m

r/?0`,}w0A)Bv+k0EXISTS 使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.Linux宝库u1ZR/H:S"I [Oe j"_F4Pz

Linux宝库o ?`Go

原文地址:http://www.linuxpk.com/14825/viewspace-11282.htmlLinux宝库,_HI8V;E
欢迎转载,转载请注明出处。

;D6{ Uu%K4u8|$y0

1O+k9PI}(L@0 Linux宝库n'x-O"Ik-? Z(AOII

EB4X0L2IN0 Linux宝库/f z P(P0`)`E!z-u

P'XM;D4?3Ln-R0 

*N2sR)V'C!E0Linux宝库,L p(em q&?T

 Linux宝库-F(l"gz4P,T

c*E:gL$Z,S0~3P)b\0 

;^7JI.^(T[0

TAG: Oracle sql语句 SQL语句 电脑 索引 文件

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

westsoftware

westsoftware

本博客与某些软件公司没有任何关系,纯属个人博客。

日历

« 2008-09-08  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 3972
  • 日志数: 8
  • 图片数: 1
  • 建立时间: 2007-03-27
  • 更新时间: 2008-06-03

RSS订阅

Open Toolbar