OracleSQL性能优化方法_第1页
OracleSQL性能优化方法_第2页
OracleSQL性能优化方法_第3页
OracleSQL性能优化方法_第4页
OracleSQL性能优化方法_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、OracleSQL性能优化方法Oracle性能优化方法(SQL篇)TOC o 1-5 h z丄综述2 HYPERLINK l bookmark4 o Current Document 表分区的应用2访咨询Table的方式3共享SQL语句3 HYPERLINK l bookmark6 o Current Document 选择最有效率的表名顺序5 HYPERLINK l bookmark8 o Current Document WHERE子句中的连接顺序.6 HYPERLINK l bookmark10 o Current Document SELECT子句中幸免使用*6 HYPERLINK l

2、 bookmark12 o Current Document 减少访咨询数据库的次数6 HYPERLINK l bookmark14 o Current Document 使用DECODE函数来减少处理时刻7 HYPERLINK l bookmark16 o Current Document 整合简单.无关联的数据库访咨询8 HYPERLINK l bookmark18 o Current Document 删除重复记录8 HYPERLINK l bookmark20 o Current Document 用TRUNCATE替代DELETE9 HYPERLINK l bookmark22 o

3、Current Document 尽量多使用COMMIT9 HYPERLINK l bookmark24 o Current Document 运算记录条数9 HYPERLINK l bookmark26 o Current Document 用Where子句替换HAVING子句9 HYPERLINK l bookmark28 o Current Document 减少对表的查询10 HYPERLINK l bookmark30 o Current Document 通过内部函数提高SQL效率.11 HYPERLINK l bookmark32 o Current Document 使用表的不

4、名(Alias)12 HYPERLINK l bookmark34 o Current Document 用EXISTS替代IN12 HYPERLINK l bookmark36 o Current Document 用NOTEXISTS替代NOTIN13 HYPERLINK l bookmark38 o Current Document 识不低效执行的SQL语句13 HYPERLINK l bookmark40 o Current Document 使用TKPROF工具来杳询SQL性能状态14 HYPERLINK l bookmark42 o Current Document 用EXPLAI

5、NPLAN分析SQL语句14 HYPERLINK l bookmark44 o Current Document 实时批量的处理161综述ORACLE数据库的性能调整是个重要,却又有难度的话题,如何有效地进行调整,需要通过反反复复的过程。在数据库建立时,就能依照顾用的需要合理设计分配表空间以及储备参数、内存使用初始化参数,对以后的数据库性能有专门大的益处,建立好后,又需要在应用中不断进行应用程序的优化和调整,这需要在大量的实践工作中不断地积存体会,从而更好地进行数据库的调优。数据库性能调优的方法调整内存调整I/O调整资源的争用咨询题调整操作系统参数调整数据库的设计调整应用程序本文针对应用程序的

6、调整,来讲明对数据库性能如何进行优化。2表分区的应用关于海量数据的表,能够考虑建立分区以提高操作效率。建立分区一样以关键字为分区的标志,也能够以其他字段作为分区的标志,但效率不如关键字高。建立分区的语句在建表时能够进行讲明:createtableTABLENAME()partitionbyrange(PutOutNo)(partitionPART1valueslessthan(200312319999)partitionPART2valueslessthan(200412319999)如此,在进行大部分数据查询,数据更新和数据插入时,Oracle自动判定操作应该在哪个分区进行,幸免了整表操作,

7、提高了执行的效率3访咨询Table的方式ORACLE采纳两种访咨询表中记录的方式:全表扫描全表扫描确实是顺序地访咨询表中每条记录.ORACLE采纳一次读入多个数据块(databaseblock)的方式优化全表扫描.通过ROWID访咨询表能够采纳基于ROWID的访咨询方式情形,提高访咨询表的效率,,ROWID包含了表中记录的物理位置信息.ORACLE采纳索引(INDEX)实现了数据和存放数据的物理位置(ROWID)之间的联系.通常索引提供了快速访咨询ROWID的方法,因此那些基于索引列的查询就能够得到性能上的提高.4共享SQL语句数据库治理员必须在init.ora中为那个区域设置合适的参数,当那

8、个内存区域越大,就能够保留更多的语句,因此被共享的可能性也就越大了.当向ORACLE提交一个SQL语句,ORACLE会第一在这块内存中查找相同的语句.那个地点需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须完全相同(包括空格,换行等).共享的语句必须满足三个条件:字符级的比较:当前被执行的语句和共享池中的语句必须完全相同.例如:SELECT*FROMEMP;和下列每一个都不同SELECT*fromEMP;Select*FromEmp;SELECT*FROMEMP;两个语句所指的对象必须完全相同:例如:用户对象名如何访咨询Jacksal_limitprivates

9、ynonymWork_citypublicsynonymPlant_detailpublicsynonymJillsal_limitprivatesynonymWork_citypublicsynonymPlant_detailtableowner下列SQL语句不能在这两个用户之间共享.selectmax(sal_cap)fromsal_limit;缘故每个用户都有一个privatesynonym-salimit,它们是不同的对象下列SQL语句能在这两个用户之间共享.selectcount(*)fromwork_citywheresdesclikeNEW%;缘故:两个用户访咨询相同的对象pub

10、licsynonym-work_city下列SQL语句不能在这两个用户之间共享.selecta.sdesc,b.locationfromwork_citya,plant_detailbwherea.city_id=b.city_id缘故:用户jack通过privatesynonym访咨询plant_detail而jill是表的所有者,对象不同.两个SQL语句中必须使用相同的名字的绑定变量(bindvariables)1.selectpin,namefrompeoplewherepin=:blk1.pin;selectpin,namefrompeoplewherepin=:blk1.pin;2.

11、selectpin,namefrompeoplewherepin=:blk1.ot_ind;selectpin,namefrompeoplewherepin=:blk1.ov_ind;5选择最有效率的表名顺序例如:表TAB116,384条记录,表TAB21条记录选择TAB2作为基础表(最好的方法)selectcount(*)fromtab1,tab2选择TAB2作为基础表(不佳的方法)selectcount(*)fromtab2,tab1假如有3个以上的表连接查询,那就需要选择交叉表(intersectiontable)作为基础表,交叉表是指那个被其他表所引用的表.例如:EMP表描述了LOCA

12、TION表和CATEGORY表的交集.SELECT*FROMLOCATIONL,CATEGORYC,EMPEWHEREE.EMP_NOBETWEEN1000AND2000ANDE.CAT_NO=C.CAT_NOANDE.LOCN=L.LOCN将比下列SQL更有效率SELECT*FROMEMPE,LOCATIONL,CATEGORYCWHEREE.CAT_NO=C.CAT_NOANDE.LOCN=L.LOCNANDE.EMP_NOBETWEEN1000AND20006WHERE子句中的连接顺序ORACLE采纳自下而上的顺序解析WHERE子句,依照那个原理,表之间的连接必须写在其他WHERE条件之

13、前,那些能够过滤掉最大数量记录的条件必须写在WHERE子句的末尾.例如:(低效)SELECTFROMEMPEWHERESAL50000ANDJOB=MANAGERAND25(SELECTCOUNT(*)FROMEMPWHEREMGR=E.EMPNO);(高效)SELECTFROMEMPEWHERE2550000ANDJOB=MANAGER;7SELECT子句中幸免使用*当在SELECT子句中列出所有的COLUMN时,使用动态SQL列引用*是一个方便的方法但是,这是一个专门低效的方法.实际上ORACLE在解析的过程中,会将*依次转换成所有的列名,那个工作是通过查询数据字典完成的,这意味着将耗费更

14、多的时刻.8减少访咨询数据库的次数当执行每条SQL语句时,ORACLE在内部执行了许多工作:解析SQL语句,估算索引的利用率,绑定变量,读数据块等等.由此可见,减少访咨询数据库的次数,就能实际上减少ORACLE的工作量.例如,以下有三种方法能够检索出雇员号等于0342或0291的职员.方法1(最低效)SELECTEMP_NAME,SALARY,GRADEFROMEMPWHEREEMP_NO=342;SELECTEMP_NAME,SALARY,GRADEFROMEMPWHEREEMP_NO=291;方法2(次低效)DECLARECURSORC1(E_NONUMBER)ISSELECTEMP_NA

15、ME,SALARY,GRADEFROMEMPWHEREEMP_NO=E_NO;BEGINOPENC1(342);FETCHC1INTO,.,.;OPENC1(291);FETCHC1INTO,.,.;CLOSEC1;END;方法3(高效)SELECTA.EMP_NAME,A.SALARY,A.GRADE,B.EMP_NAME,B.SALARY,B.GRADEFROMEMPA,EMPBWHEREA.EMP_NO=342ANDB.EMP_NO=291;9使用DECODE函数来减少处理时刻使用DECODE函数能够幸免重复扫描相同记录或重复连接相同的表.例如:SELECTCOUNT(*),SUM(SA

16、L)FROMEMPWHEREDEPT_NO=0020ANDENAMELIKESMITH%;SELECTCOUNT(*),SUM(SAL)FROMEMPWHEREDEPT_NO=0030ANDENAMELIKESMITH%;你能够用DECODE函数高效地得到相同结果SELECTCOUNT(DECODE(DEPT_NO,0020,X,NULL)D0020_COUNT,COUNT(DECODE(DEPT_NO,0030,X,NULL)D0030_COUNT,SUM(DECODE(DEPT_NO,0020,SAL,NULL)D0020_SAL,SUM(DECODE(DEPT_NO,0030,SAL,N

17、ULL)D0030_SALFROMEMPWHEREENAMELIKESMITH%;类似的,DECODE函数也能够运用于GROUPBY和ORDERBY子句中.10整合简单,无关联的数据库访咨询假如有几个简单的数据库查询语句,能够把它们整合到一个查询中(即使它们之间没有关系)例如:SELECTNAMEFROMEMPWHEREEMP_NO=1234;SELECTNAMEFROMDPTWHEREDPT_NO=10;SELECTNAMEFROMCATWHERECAT_TYPE=RD;上面的3个查询能够被合并成一个:SELECTE.NAME,D.NAME,C.NAMEFROMCATC,DPTD,EMPE,

18、DUALXWHERENVL(X,X.DUMMY)=NVL(X,E.ROWID(+)ANDNVL(X,X.DUMMY)=NVL(X,D.ROWID(+)ANDNVL(X,X.DUMMY)=NVL(X,C.ROWID(+)ANDE.EMP_NO(+)=1234ANDD.DEPT_NO(+)=10ANDC.CAT_TYPE(+)=RD;尽管采取这种方法,效率得到提高,然而程序的可读性大大降低,因此依旧要权衡之间的利弊11删除重复记录最高效的删除重复记录方法(因为使用了ROWID)DELETEFROMEMPEWHEREE.ROWID(SELECTMIN(X.ROWID)FROMEMPXWHEREX.E

19、MP_NO=E.EMP_NO);用TRUNCATE替代DELETE当删除表中的记录时,在通常情形下,回滚段(rollbacksegments)用来存放能够被复原的信息.假如你没有COMMIT事务,ORACLE会将数据复原到删除之前的状态(准确地讲是复原到执行删除命令之前的状况)而当运用TRUNCATE时,回滚段不再存放任何可被复原的信息.当命令运行后,数据不能被复原.因此专门少的资源被调用,执行时刻也会专门短.(注意:TRUNCATE只在删除全表适用,TRUNCATE是DDL不是DML)尽量多使用COMMIT只要有可能,在程序中尽量多使用COMMIT,如此程序的性能得到提高,需求也会因为COM

20、MIT所开释的资源而减少:COMMIT所开释的资源:回滚段上用于复原数据的信息.被程序语句获得的锁redologbuffer中的空间ORACLE为治理上述3种资源中的内部花费14运算记录条数和一样的观点相反,count(*)比count(l)稍快,因此假如能够通过索引检索,对索引列的计数仍旧是最快的.例如COUNT(EMPNO)(并不十分准确,通过实际的测试,上述三种方法并没有显著的性能差不)15用Where子句替换HAVING子句幸免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤.那个处理需要排序,总计等操作.假如能通过WHERE子句限制记录的数目,那就能减少这

21、方面的开销.例如:低效:SELECTREGION,AVG(LOG_SIZE)FROMLOCATIONGROUPBYREGIONHAVINGREGIONREGION!=SYDNEYANDREGION!=PERTH高效SELECTREGION,AVG(LOG_SIZE)FROMLOCATIONWHEREREGIONREGION!=SYDNEYANDREGION!=PERTHGROUPBYREGION(HAVING中的条件一样用于对一些集合函数的比较,如COUNT()等等.除此而外,一样的条件应该写在WHERE子句中)16减少对表的查询在含有子查询的SQL语句中,要专门注意减少对表的查询.例如:低效

22、SELECTTAB_NAMEFROMTABLESWHERETAB_NAME=(SELECTTAB_NAMEFROMTAB_COLUMNSWHEREVERSION=604)ANDDB_VER=(SELECTDB_VERFROMTAB_COLUMNSWHEREVERSION=604)高效SELECTTAB_NAMEFROMTABLESWHERE(TAB_NAME,DB_VER)=(SELECTTAB_NAME,DB_VER)FROMTAB_COLUMNSWHEREVERSION=604)Update多个Column例子:低效:UPDATEEMPSETEMP_CAT=(SELECTMAX(CATEG

23、ORY)FROMEMP_CATEGORIES),SAL_RANGE=(SELECTMAX(SAL_RANGE)FROMEMP_CATEGORIES)WHEREEMP_DEPT=0020;高效:UPDATEEMPSET(EMP_CAT,SAL_RANGE)=(SELECTMAX(CATEGORY),MAX(SAL_RANGE)FROMEMP_CATEGORIES)WHEREEMP_DEPT=0020;17通过内部函数提高SQL效率.SELECTH.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC,COUNT(*)FROMHISTORY_TYPET,EMPE,EMP_HI

24、STORYHWHEREH.EMPNO=E.EMPNOANDH.HIST_TYPE=T.HIST_TYPEGROUPBYH.EMPNO,E.ENAME,H.HIST_TYPE,T.TYPE_DESC;通过调用下面的函数能够提高效率.FUNCTIONLOOKUP_HIST_TYPE(TYPINNUMBER)RETURNVARCHAR2ASTDESCVARCHAR2(30);CURSORC1ISSELECTTYPE_DESCFROMHISTORY_TYPEWHEREHIST_TYPE=TYP;BEGINOPENC1;FETCHC1INTOTDESC;CLOSEC1;RETURN(NVL(TDESC,

25、?);END;FUNCTIONLOOKUP_EMP(EMPINNUMBER)RETURNVARCHAR2ASENAMEVARCHAR2(30);CURSORC1ISSELECTENAMEFROMEMPWHEREEMPNO=EMP;BEGINOPENC1;FETCHC1INTOENAME;CLOSEC1;RETURN(NVL(ENAME,?);END;SELECTH.EMPNO,LOOKUP_EMP(H.EMPNO),H.HIST_TYPE,LOOKUP_HIST_TYPE(H.HIST_TYPE),COUNT(*)FROMEMP_HISTORYHGROUPBYH.EMPNO,H.HIST_TY

26、PE;18使用表的不名(Alias)当在SQL语句中连接多个表时,请使用表的不名并把不名前缀于每个Column上.如此一来,就能够减少解析的时刻并减少那些由Column歧义引起的语法错误.(Column歧义指的是由于SQL中不同的表具有相同的Column名,当SQL语句中显现那个Column时,SQL解析器无法判定那个Column的归属)用EXISTS替代IN在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接.在这种情形下,使用EXISTS(或NOTEXISTS)通常将提高查询的效率.低效:SELECT*FROMEMP(基础表)WHEREEMPNO0ANDDEPTNOIN(

27、SELECTDEPTNOFROMDEPTWHERELOC=MELB)高效:SELECT*FROMEMP(基础表)WHEREEMPNO0ANDEXISTS(SELECTXFROMDEPTWHEREDEPT.DEPTNO=EMP.DEPTNOANDLOC=MELB)用NOTEXISTS替代NOTIN在子查询中,NOTIN子句将执行一个内部的排序和合并不管在哪种情形下,NOTIN差不多上最低效的(因为它对子查询中的表执行了一个全表遍历).为了幸免使用NOTIN,我们能够把它改写成外连接(OuterJoins)或NOTEXISTS.例如:SELECTFROMEMPWHEREDEPT_NONOTIN(S

28、ELECTDEPT_NOFROMDEPTWHEREDEPT_CAT=A);为了提高效率.改写为:(方法一:高效)SELECT.FROMEMPA,DEPTBWHEREA.DEPT_NO=B.DEPT(+)ANDB.DEPT_NOISNULLANDB.DEPT_CAT(+)=A(方法二:最高效)SELECT.FROMEMPEWHERENOTEXISTS(SELECTXFROMDEPTDWHERED.DEPT_NO=E.DEPT_NOANDDEPT_CAT=A);21识不低效执行的SQL语句用下列SQL工具找出低效SQL:SELECTEXECUTIONS,DISK_READS,BUFFER_GETS,ROUND(BUFFER_GETS-DISK_READS)/BUFFER_GETS,2)Hit_radio,ROUND(DISK_READS/EXECUTIONS,2)Reads_per_run,SQL_TEXTFROMV$SQLAREAWHEREEXECUTIONS0ANDBUFFER_GETS0AND(BUFFER_GETS-DISK_READS)/BUFFER_GETSlistSELECT*FROMdept,emp3*WHEREemp.deptno=dept.deptnoSQLsetautotracetraceonly/*

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论