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

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

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

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

;Xwb(dPv2vcq0

4?Uvsa+EaLc0以下的实例中使用3个表 (TABLE) A(R1,R2,R3,R4,R5,C1,C2,B2) B(R1,B1,B2) C(R1,C1,C2,B2),括号中即为表中的字段 Linux宝库1PUR@5SM

Linux宝库f if r,A6y

一、使用特定表中的索引Linux宝库k]xu"K(sv'z(x-J
    有时候一个表中的数据量很大时候,索引是非常非常的重要,何为索引?我来举个例子,你一听就能明白,比如:你想搜索我的电脑中一个名字为FILE.TXT文件,如果不知道该文件所在的目录(没有创建索引)情况下,基本上要扫描我的电脑中的所有盘符里的文件,如果你的硬盘中的有很多文件(相当一个表中有很多的数据),基本上是一个全盘扫描的过程,这时如果你告诉搜索,你的文件就在D盘的TEST目录下,这样来搜索速度将会大大的提高,给文件定位就相当一个索引。Linux宝库%iJO1RA8Vf#Y
    好了,知道索引是干什么之后,下面来看看怎么走正确的索引,才能达到最高效。假如A表中有两个索引IDX_R1 INDEX(R1,R2,R4,R5),IDX_R3 INDEX(R1,R3,R4,R5) 现在需要做这样的操作,显示表中的条件值是R1 = 1,R3 = 3,R4 =4的所有内容。通常我们会写出下面的查询语句。Linux宝库H1j5L'Wv#Hh&j5R
    select * from A where R1 =1 and R3 =3 and R4;
:f`3K[Y0u_`wL0按道理它走的索引是IDX_R3,有时候默认走的索引并不是你想象中的那样,特别是多表关联的情况下。所以我们进行指定一下索引,按我们真正想要的走的索引:Linux宝库c9A![q [
   select /*+ index(R1,IDX_R3) */* from A where R1 =1 and R3 =3 and R4;Linux宝库;[E&clu9h'S#Fw6b

Y0S/|9QFM4c0二、在检索数据的时候两个表的关联查询效率低于使用EXISTS子句。
XA&UyL ns+Q4A/s0   SELECT  B.R1,B.B1,B.B2 FROM A,B WHERE A.R1 = B.R1;
"a0f(\DZA]0   优化为:
y;PFk$xj,y!l {fE0   SELECT  B.R1,B.B1,B.B2 FROM B WHERE EXISTS(SELECT 1 FROM A WHERE A.R1 = B.R1);Linux宝库"Pj*j+Y0D(m4v
   如果你在WINDOWS的ORACLE的平台可以使用PL/SQL中的执行计划(EXPLAIN PLAN),看一下相应的执行时间进行验证。Linux宝库$H^-aB2WJ.M

Linux宝库m"w;a ~z _IJ X

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

/}s!~"n0O/}5kM0

0V9eu/h;V.B#P0q8G0四、 使用EXISTS代替IN子句,同理用NOT EXISTS 代替NOT INLinux宝库'p ^Qea5Y*w%t#^*_.N0P

bxU3y'Ciw0因为使用IN子句作为一个查询条件后,ORACLE会将IN子句的数据先搜索出来以后,等结果集返回以后才作为一个条件值。而EXISTS语句是WHERE语句之前的数据优先检索完后在去检索EXISTS子句的内容。Linux宝库#u4KG4\J,Pm9b5N

Linux宝库m5K/]!H"wd(k;W

五、如果有子句比较的情况下,将此比较语句放到WHERE后作为第一个条件。
;d!}\T(|*c9dG0如:Linux宝库1jJS9w} I-g(E|X

j7]Z:t!^[bS e0SELECT A.R2 FROM A WHERE B.B2 = 3 AND 2< SELECT COUNT(1) FROM B WHERE B.R1 = A.R1;  //效率较低Linux宝库(x CAJa*aylMK

6?7i"kc? A(U9Yeg0SELECT A.R2 FROM A WHERE 2< SELECT COUNT(1) FROM B WHERE B.R1 = A.R1 AND B.B2 = 3;  //效率较高

*_f5h5g%K ~7J"P1zI0Linux宝库if"\g.\"Znc!w8L9|

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

/~#iE7wK5B0

R5Um1|dU0七、在执行数据检索的过程中近可能少的访问同一个表。

:TF9d` D9v7Ng7t0

N*KFR-x0X0在写存储过程的时候,有时候因为条件值不一样,通常需要多次的去访问同一个表,这个时候可以考虑一个使用DECODE函数来代替多个条件。

vs qmS SI0Linux宝库0U"n$Vx I6U _k

//1
g [)F e0hyS,K0SELECT SUM(Nvl(C2,0)) FROM C WHERE R1 = 12 AND C1 = 22 ;
)gm5E#F1?!B1]0//2Linux宝库IG5r,rHH HdT
SELECT SUM(Nvl(C2,0)) FROM C WHERE R1 = 12 AND C1 = 33 ;

cX)I%X(}:L8Q4G0

)}B,[!r}@G)H0优化方法:
-X ms-\A.A/_l0SELECT SUM(DECODE(C1,22,C2,33,C2,0) FROM C WHERE R1 =12 AND C1 IN(22,33);

"VbJ gF2M0Linux宝库SqCZ#Sl

八、在写条件的时候尽量在条件值的左边使用函数。Linux宝库Z%}8c6a$S5Xt\X
如:

H(gz+bH:M0Linux宝库'wG$Pgc.{

SELECT * FROM A WHERE TO_CHAR(R5,'YYYYMM') = '200804'Linux宝库 ju |z0^)Z(}ED-Dw$W/}

}5K}Y+Pi%q s6J6Y:L+b0应该使用Linux宝库X!p1zp3ef}k3E

Cl/G5SY1r4r.]0SELECT * FROM A WHERE R5 = TO_DATE('200804','YYYYMM');代替

/`/Q9M o2le/k0

dz}g_E F!y0
s+\Ey k"]UEP0九、UPDATE语句写法提高效率。Linux宝库T3m qf^;?|'i

Linux宝库|[e,U&R AMLr

UPDATE ALinux宝库+J!n`{NA#N%?
SET C2 = (SELECT MAX(C2) FROM C),Linux宝库B4XN mh-dxMQ(M
    B2 = (SELECT MAX(B2) FROM C)Linux宝库W#F$nNEK
WHERE R1 = 1000;Linux宝库L!~] u!r"{.jw
高效:
M:pH#rY1A,_j0UPDATE A
MGX AzF.V0SET (C2, B2)
c"N A4?N(S0= (SELECT MAX(C2) , MAX(B2)Linux宝库E/j0Z@ ^} K]%Ab
FROM C)
6WRM-q"c Y0WHERE R1 = 1000;

j3O#Kj`rz!S0

r o!Y G9Lt1w7~0Linux宝库*C6G!r"MGq
十、用EXISTS替换DISTINCT.

} R:@ g.v| |0

7nH0E L4oY1[U0例如:
:}6UF4E:z4u ml6j G0//低效:Linux宝库?y_ [ K7O0Qr
SELECT DISTINCT C.R1,C.B2
|E6y!Q!i \Fv0FROM A,CLinux宝库P#wqQ&jrgG
WHERE A.R1 = C.R1 ;Linux宝库;\&JfZ NY%aD S,] w

Linux宝库`ZyY I*MI1I sy

//高效:Linux宝库xsf)~j:r%?O
SELECT C.R1,C.B2
VQcwH0FROM C
zD] _6S-vW0os0WHERE EXISTS ( SELECT ‘X’
Y7Qn%]K B9D t0FROM A
6C$JY"ik z|0WHERE A.R1 = C.R1);

uV3fo'v0

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

W8Q Ik{8M5i8D0

wG8w)LJ8z0原文地址:http://www.linuxpk.com/14825/viewspace-11282.html
gM&|8hL)k8[T"R(o:d0欢迎转载,转载请注明出处。

/W'J$\4~0E)Qvf%j v9]0

n A0N5\&A&y0 Linux宝库`R|dE

Linux宝库 J~-p k.l:b@I*G(sc

 Linux宝库!b r&V@;u$E

V;K?qX:@ |!A0 

nGF6B2a)NM0Linux宝库$Gph#e QG*f9aW

 

Yv$\_/|'w.t3A0Linux宝库CZ l,` z

 

xY\~\3R0

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

 

评分:0

我来说两句

显示全部

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

westsoftware

westsoftware

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

数据统计

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

RSS订阅

Open Toolbar