您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > 优化oracle的相关资料
优化ORACLE的响应速度资料(一)资料编号NO101Oraclesql语句执行顺序sql语法的分析是从右到左一、sql语句的执行步骤:1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。3)视图转换,将涉及视图的查询语句转换为相应的对基表查询语句。4)表达式转换,将复杂的SQL表达式转换为较简单的等效连接表达式。5)选择优化器,不同的优化器一般产生不同的“执行计划”6)选择连接方式,ORACLE有三种连接方式,对多表连接ORACLE可选择适当的连接方式。7)选择连接顺序,对多表连接ORACLE选择哪一对表先连接,选择这两表中哪个表做为源数据表。8)选择数据的搜索路径,根据以上条件选择合适的数据搜索路径,如是选用全表搜索还是利用索引或是其他的方式。9)运行“执行计划”(注意:oracle优化下面有介绍)二、oracle共享原理:ORACLE将执行过的SQL语句存放在内存的共享池(sharedbufferpool)中,可以被所有的数据库用户共享。当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同,ORACLE就能很快获得已经被解析的语句以及最好的执行路径.。这个功能大大地提高了SQL的执行性能并节省了内存的使用。三、oracle语句提高查询效率的方法:1:wherecolumnin(select*from...where...);2:...whereexists(select'X'from...where...);第二种格式要远比第一种格式的效率高。在Oracle中可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间Oracle系统在执行IN子查询时,首先执行子查询,并将获得的结果列表存放在在一个加了索引的临时表中。避免使用having子句。HAVING只会在检索出所有记录之后才对结果集进行过滤。这个处理需要排序,总计等操作。如果能通过WHERE子句限制记录的数目,那就能减少这方面的开销。四、SQLSelect语句完整的执行顺序:1、from子句组装来自不同数据源的数据;2、where子句基于指定的条件对记录行进行筛选;3、groupby子句将数据划分为多个分组;4、使用聚集函数进行计算;5、使用having子句筛选分组;6、计算所有的表达式;7、select的字段;8、使用orderby对结果集进行排序。SQL语言不同于其他编程语言的最明显特征是处理代码的顺序。在大多数据库语言中,代码按编码顺序被处理。但在SQL语句中,第一个被处理的子句式FROM,而不是第一出现的SELECT。SQL查询处理的步骤序号:1SELECT(9)DISTINCT(11)TOP_specificationselect_list2(1)FROMleft_table3(3)join_typeJOINright_table4(2)ONjoin_condition5(4)WHEREwhere_condition6(5)GROUPBYgroup_by_list7(6)WITH{CUBE|ROLLUP}8(7)HAVINGhaving_condition9(10)ORDERBYorder_by_list以上每个步骤都会产生一个虚拟表,该虚拟表被用作下一个步骤的输入。这些虚拟表对调用者(客户端应用程序或者外部查询)不可用。只有最后一步生成的表才会会给调用者。如果没有在查询中指定某一个子句,将跳过相应的步骤。逻辑查询处理阶段简介:1、FROM:对FROM子句中的前两个表执行笛卡尔积(交叉联接),生成虚拟表VT1。2、ON:对VT1应用ON筛选器,只有那些使为真才被插入到TV2。3、OUTER(JOIN):如果指定了OUTERJOIN(相对于CROSSJOIN或INNERJOIN),保留表中未找到匹配的行将作为外部行添加到VT2,生成TV3。如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表位置。4、WHERE:对TV3应用WHERE筛选器,只有使为true的行才插入TV4。5、GROUPBY:按GROUPBY子句中的列列表对TV4中的行进行分组,生成TV5。6、CUTE|ROLLUP:把超组插入VT5,生成VT6。7、HAVING:对VT6应用HAVING筛选器,只有使为true的组插入到VT7。8、SELECT:处理SELECT列表,产生VT8。9、DISTINCT:将重复的行从VT8中删除,产品VT9。10、ORDERBY:将VT9中的行按ORDERBY子句中的列列表顺序,生成一个游标(VC10)。11、TOP:从VC10的开始处选择指定数量或比例的行,生成表TV11,并返回给调用者。(二)资料编号NO102最近在JavaEye上发现好多同志对sql的优化好像是知道的很少,最近总结了几条仅供参考,不过除少数可能要依情况而定,大多数还是相当有效的。【注:以下说的(低效)与(高效)都是相当来说的。】1、Where子句中的连接顺序:ORACLE采用自下而上的顺序解析WHERE子句。根据这个原理,表之间的连接必须写在其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾。举例:(低效)select...fromtable1t1wheret1.sal300andt1.jobtype='0001'and20(selectcount(*)fromtable1t2wheret2.pno=t1.tno;(高效)select...fromtable1t1where20(selectcount(*)fromtable1t2wheret2.pno=t1.tnoandt1.sal300andt1.jobtype='0001';2、Select子句中避免使用“*”:当你想在select子句中列出所有的column时,使用动态SQL列引用‘*'是一个方便的方法。不幸的是,这是一个非常低效的方法。实际上,ORACLE在解析的过程中,会将'*'依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间。3、减少访问数据库的次数:当执行每条SQL语句时,ORACLE在内部执行了许多工作:解析SQL语句、估算索引的利用率、绑定变量、读数据块等等。由此可见,减少访问数据库的次数,就能实际上减少ORACLE的工作量。举例:题目——我要查找编号为0001、0002学生的信息。(低效)selectname,age,gender,addressfromt_studentwhereid='0001';selectname,age,gender,addressfromt_studentwhereid='0002';(高效)selecta.name,a.age,a.gender,a.address,b.name,b.age,b.gender,b.addressfromt_studenta,t_studentbwherea.id='0001'andb.id='0002';4、使用Decode函数来减少处理时间:使用DECODE函数可以避免重复扫描相同记录或重复连接相同的表。举例:(低效)selectcount(*),sum(banace)fromtable1wheredept_id='0001'andnamelike'anger%';selectcount(*),sum(banace)fromtable1wheredept_id='0002'andnamelike'anger%';(高效)selectcount(decode(dept_id,'0001','XYZ',null))count_01,count(decode(dept_id,'0002','XYZ',null))count_02,sum(decode(dept_id,'0001',dept_id,null))sum_01,sum(decode(dept_id,'0002',dept_id,null))sum_02fromtable1wherenamelike'anger%';5、整合简单,无关联的数据库访问:如果你有几个简单的数据库查询语句,你可以把它们整合到一个查询中(即使它们之间没有关系)举例:(低效)selectnamefromtable1whereid='0001';selectnamefromtable2whereid='0001';selectnamefromtable3whereid='0001';(高效)selectt1.name,t2.name,t3.namefromtable1t1,table2t2,table3t3wheret1.id(+)='0001'andt2.id(+)='0001'andt3.id(+)='0001'【注:上面例子虽然高效,但是可读性差,需要量情而定啊!】6、删除重复记录:最高效的删除重复记录方法(因为使用了ROWID)举例:deletefromtable1t1wheret1.rowid(selectmin(t2.rowid)fromtable1t2wheret1.id=t2.id);7、尽量不要使用having子句,可以考虑用where替换。having只会在检索出所有记录之后才对结果集进行过滤.这个处理需要排序,总计等操作。如果能通过where子句限制记录的数目,那就能减少这方面的开销。8、尽量用表的别名:当在SQL语句中连接多个表时,请使用表的别名并把别名前缀于每个Column上。这样一来,就可以减少解析的时间并减少那些由Column歧义引起的语法错误。9、用exists替代in(发现好多程序员不知道这个怎么用):在许多基于基础表的查询中,为了满足一个条件,往往需要对另一个表进行联接。在这种情况下,使用exists(或notexists)通常将提高查询的效率。举例:(低效)select...fromtable1t1wheret1.id10andpnoin(selectnofromtable2wherenamelike');(高效)select...fromtable1t1wheret1.id10andexists(select1fromtable2t2wheret1.pno=t2.noandnamelike');10、用notexists替代notin:在子查询中,notin子句将执行一个内部的排序和合并。无论在哪种情况下,notin都是最低效的(因为它对子查询中的表执行了一个全表遍历)。为了避免使用notin,我们可以把它改写成外连接(OuterJoins)或notexists。11、用exists替换distinct:当提交一个包含一对多表信息的查询时,避免在select子句中使用distinct.一般可以考虑用exists替换举例:(低效)selectdistinctd.dept_no,d.dept_namefromt_deptd,t_empewhered.dept_no=e.dept_no;(高效)selectd.dept_no,d.dept_namefromt_deptdwhereexists(select1fromt_empwhered.dept_no=e.dept_no);exists使查询更为迅速,因为RDBMS核心模块将在子查询的条件一旦满足后,立刻返回结果.12、用表连接替换exists:通常来说,采用表连接的方式比exists更有效率。举例:(低效)selectenamefromempewhereexists(select1fromdeptwheredept_no=e.dept_noanddept_cat='W');SELECTENAME(高效)s
本文标题:优化oracle的相关资料
链接地址:https://www.777doc.com/doc-5358045 .html