Oracle执行计划.pptx
《Oracle执行计划.pptx》由会员分享,可在线阅读,更多相关《Oracle执行计划.pptx(65页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Oracle执行计划解读 培训教师培训教师:谢高兴谢高兴 时时 间间:2006.4.27 BEGINSQL执行过程1,解析SQL2,执行3,显示结果集4,转换字段数据检查安全性检查SQL语法 查询重新书写 创建执行计划创建执行计划捆绑执行计划执行执行计划读取结果集执行计划执行计划执行计划:Oracle Oracle内部的机器级代码内部的机器级代码,决定如何访问决定如何访问存储器,得到需要的结果集。存储器,得到需要的结果集。执行计划的主要内容:访问方式,访问执行计划的主要内容:访问方式,访问顺序。顺序。得到执行计划的方式1.Explain1.Explain(解释)(解释)2.Autotrace(
2、2.Autotrace(自动跟踪自动跟踪)3.3.其他工具其他工具基本格式:基本格式:explain plan set STATEMENT_ID=testplanFor Select.(Select,insert,update 等数据操作语句均可等数据操作语句均可)基本使用方式:基本使用方式:SQL set autotrace on;(SQL PLUS中使用中使用)准备:创建准备:创建Plan_table表表create table plan_table(statement_id varchar2(30),timestamp date,remarks varchar2(80),operatio
3、n varchar2(30),options varchar2(30),object_node varchar2(128),object_owner varchar2(30),object_name varchar2(30),object_instance integer,object_type varchar2(30),optimizer varchar2(255),search_columns integer,id integer,parent_id integer,position integer,cost integer,cardinality integer,bytes intege
4、r,other_tag varchar2(255),partition_start varchar2(255),partition_stop varchar2(255),partition_id integer,other long,distribution varchar2(30);AUTO TRACESQL set autotrace on;SQL select*from dual;D-XExecution Plan-0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS(FULL)OF DUALStatistics-0 recursive
5、 calls 0 db block gets 3 consistent gets 0 physical reads 0 redo size 372 bytes sent via SQL*Net to client 511 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts(memory)0 sorts(disk)1 rows processedSQL统计信息统计信息执行计划执行计划结果数据结果数据使用使用Explain1,1,删除上次解析数据删除上次解析数据2,2,执行解析执行解析
6、delete from plan_table where STATEMENT_ID=testplan;explain plan set STATEMENT_ID=testplanexplain plan set STATEMENT_ID=testplanfor select*from dual;for select*from dual;3,3,显示执行计划显示执行计划select lpad(,5*(level-1)|operation operation,options,object_name,cost,position from plan_table start with id=0 and
7、STATEMENT_ID=testplan connect by prior id=parent_id;第一个执行第一个执行 计划计划对应对应SQLSQL语句:语句:select*from dual;select*from dual;执行计划执行计划:怎样看执行计划执行计划其实是一棵树,层次最深的最先执行,层次执行计划其实是一棵树,层次最深的最先执行,层次相同,上面的先执行。显示时已经按照层次缩进,因相同,上面的先执行。显示时已经按照层次缩进,因此从最里面的看起。最后一组就是驱动表。例:此从最里面的看起。最后一组就是驱动表。例:驱动表 select count(*)from prm_adjus
8、tprice main,prm_adjustprice_b detail where main.cadjpriceid=detail.CADJPRICEID and main.DADJPRICEDATE=2004-04-18 and detail.CINVENTORYID in(select pk_invmandoc from bd_invmandoc where bd_invmandoc.SEALFLAG=N);表访问方式表访问方式散列获取:散列获取:全表扫描:全表扫描:ROWIDROWID访问:访问:读取表的每一条记录,顺序地从第一个数据块开始知道结尾读取表的每一条记录,顺序地从第一个数据
9、块开始知道结尾标志。标志。ROWID包含记录的数据块号和数据块中的偏移量。因此它包含记录的数据块号和数据块中的偏移量。因此它是获取一条记录的最快的方法。是获取一条记录的最快的方法。使用散列算法得到符号关键值的来确定记录所在的数据块。使用散列算法得到符号关键值的来确定记录所在的数据块。它能减少数据读入量,但是存在重新定位记录的问题,只能它能减少数据读入量,但是存在重新定位记录的问题,只能在静态表中使用。在静态表中使用。索引访问方式索引访问方式快速全索引扫描:快速全索引扫描:索引扫描:索引扫描:从索引中读取一个或多个从索引中读取一个或多个ROWID。索引值通常按照升序方式扫描。索引值通常按照升序方
10、式扫描。有些查询可以不扫描表只扫描索引就能得到期望的查询结果。所有些查询可以不扫描表只扫描索引就能得到期望的查询结果。所有查询字段都在索引中指定有查询字段都在索引中指定;查询返回大于索引所有记录数的查询返回大于索引所有记录数的10%;进行进行Count(*)操作。操作。OracleOracle索索引引表连接操作表连接操作11,1,嵌套循环连接嵌套循环连接-NESTED LOOP-NESTED LOOP两个表,一个小的内部表和一个外部表两个表,一个小的内部表和一个外部表一般情况下速度较快,特别是中间结果集非常小的情况下一般情况下速度较快,特别是中间结果集非常小的情况下速度快。速度快。外部表索引外
11、部表索引内部表内部表外部表外部表表连接操作表连接操作22,2,散列连接散列连接-HASH JOIN-HASH JOIN两个表,一个较小的驱动表和一个大表两个表,一个较小的驱动表和一个大表中间结果集非常大的情况下速度较快。中间结果集非常大的情况下速度较快。Hash_Area_Size RAMHash_Area_Size RAM驱动表驱动表大表大表散列访问散列访问 ROWID ROWIDRAM溢出使用临时表空间溢出使用临时表空间表连接操作表连接操作33,3,排序合并连接排序合并连接-MERGE JOIN-MERGE JOIN两个表都使用全表扫描,分别进行排序,然后再合并成查两个表都使用全表扫描,分
12、别进行排序,然后再合并成查询的结果集。询的结果集。极少情况适合。只有包含两个表的决大多数记录的查询适极少情况适合。只有包含两个表的决大多数记录的查询适合。合。A A表全表扫描表全表扫描B B表全表扫描表全表扫描A A表排序表排序B B表排序表排序输出结果集输出结果集合并合并Step1:全表扫描全表扫描对查询影响最大的就是全表扫描对查询影响最大的就是全表扫描-Table Access Full.-Table Access Full.计执行划中所有的全表扫描都值得怀疑计执行划中所有的全表扫描都值得怀疑.除非是数据量非常小的表除非是数据量非常小的表可能引起全表扫描的原因:可能引起全表扫描的原因:表上
13、没有索引表上没有索引没有没有WHEREWHERE条件条件对索引字段使用了内置函数,如对索引字段使用了内置函数,如 To(Dcredate)=2005-02-15 To(Dcredate)=2005-02-15LikeLike操作符而参数以操作符而参数以“%”“%”开始开始表记录非常少表记录非常少Step2:驱动表驱动表1驱动表驱动表最内层的驱动表是不是能在执行过程中得到最小的中间数据集?最内层的驱动表是不是能在执行过程中得到最小的中间数据集?例如:查询销售订单明细,涉及三个表,订单主表,订单附表例如:查询销售订单明细,涉及三个表,订单主表,订单附表,存货存货基本档案表。条件中包含:订单日期等于
14、某天和存货编码等于某个值。基本档案表。条件中包含:订单日期等于某天和存货编码等于某个值。方案一:如果以订单主表为驱动表,可以使用日期上的索引过滤出所方案一:如果以订单主表为驱动表,可以使用日期上的索引过滤出所有的当天的订单,然后关联附表,最后再关联到存货档案表,过滤出有的当天的订单,然后关联附表,最后再关联到存货档案表,过滤出相应存货。相应存货。订单附表订单附表订单主表订单主表存货档案表存货档案表日期索引日期索引主表主表PK索引索引存货主存货主键索引键索引Step2:驱动表驱动表2方案二:如果以存货档案为驱动表,可以使用编码上的索引过滤出所方案二:如果以存货档案为驱动表,可以使用编码上的索引过
15、滤出所有存货,然后关联订单附表,得到所有存货符合条件的订单附表记录,有存货,然后关联订单附表,得到所有存货符合条件的订单附表记录,最后再用订单附表上的主表主键关联主表,判断订单主表上的日期是最后再用订单附表上的主表主键关联主表,判断订单主表上的日期是否符合条件,最后得到结果集。否符合条件,最后得到结果集。订单附表订单附表订单主表订单主表存货档案表存货档案表编码索引编码索引存货存货ID索引索引主表主主表主键索引键索引结论:如果按照存货去过滤,得到订单附表上符合条件记录会较少,结论:如果按照存货去过滤,得到订单附表上符合条件记录会较少,认为方案二更优。认为方案二更优。Step3:不该建的索引不该建
16、的索引错误索引:错误索引:对于只有少数一个可能值的列,不应该建索引。如单据状态,单据对于只有少数一个可能值的列,不应该建索引。如单据状态,单据主表上的部门人员,附表上的仓库,库存组织等。主表上的部门人员,附表上的仓库,库存组织等。索引不是越多越好。数据的插入,删除和修改都需要维护索引表,索引不是越多越好。数据的插入,删除和修改都需要维护索引表,也是有成本的。也是有成本的。建议建索引的列。所有可能用做查询条件的日期列建议建索引的列。所有可能用做查询条件的日期列,客户列;附表客户列;附表上的主表主键列,存货列,来源单据列;基本档案的编码列等。上的主表主键列,存货列,来源单据列;基本档案的编码列等。
17、Step4:复合索引列顺序复合索引列顺序对复合索引,应将重复值少的列作为先导列对复合索引,应将重复值少的列作为先导列例如订单附表上有来源单据类型例如订单附表上有来源单据类型(srctype)(srctype)和来源单据和来源单据ID(srcid),ID(srcid),建建立索引的顺序应该是立索引的顺序应该是srcid,srctype.srcid,srctype.如果将如果将srctypesrctype列作为先导列,列作为先导列,可能在查询时,没有可能在查询时,没有srcidsrcid的条件也使用这个索引扫描,其结果是扫的条件也使用这个索引扫描,其结果是扫描了大半个表,比全表扫描还慢。描了大半个
18、表,比全表扫描还慢。Step5:非最优索引非最优索引对一个表存在多个索引的列作为条件,解析中可能使用了非最优索引对一个表存在多个索引的列作为条件,解析中可能使用了非最优索引使用提示,指定使用某个索引使用提示,指定使用某个索引(存在存在SQLSQL兼容问题,不推荐兼容问题,不推荐)将索引尽可能多的使用条件将索引尽可能多的使用条件使用内置函数或运算使不想使用的条件列失效。使用内置函数或运算使不想使用的条件列失效。整型数据列整型数据列+0+0字符型加字符型加trimtrim函数函数例如:在进行调拨的时候需要判断这个仓库中此存货不存在没有记帐的出库单例如:在进行调拨的时候需要判断这个仓库中此存货不存在
19、没有记帐的出库单 Select count(*)from XXX where pk_inv=:1 and status=0 这个查询会用到存货索引,但是速度还是慢。但是仔细分析会发现,其这个查询会用到存货索引,但是速度还是慢。但是仔细分析会发现,其实实际运行中没记帐的出库单比例很少,如果在存货索引上再加上状态实实际运行中没记帐的出库单比例很少,如果在存货索引上再加上状态列,可以过滤更少的数据,速度将大大提高。列,可以过滤更少的数据,速度将大大提高。Step6:数据非均匀分布数据非均匀分布对于某些对于某些SQLSQL可能存在时快时慢,这个即可能是数据的分布不均导致可能存在时快时慢,这个即可能是数
20、据的分布不均导致举例:做销售订单时,去判断此客户是否存在未结算订单。举例:做销售订单时,去判断此客户是否存在未结算订单。SQLSQL语句:语句:这个语句在做多数客户的时候没有感觉,但是在做某一两个客户时速度奇这个语句在做多数客户的时候没有感觉,但是在做某一两个客户时速度奇慢,查其执行计划,也使用了主表上的客户索引。慢,查其执行计划,也使用了主表上的客户索引。Select.From so_order,so_order_b,.where so_order.pk=so_order_b.pk and ccustomerid=:1 and.最后发现情况是这样的:企业是做批发业务的,政策法规上不允许直接销
21、最后发现情况是这样的:企业是做批发业务的,政策法规上不允许直接销售给个人,内部职工需要购买时都是按照统一个特定的客户开票,因此数售给个人,内部职工需要购买时都是按照统一个特定的客户开票,因此数据库中数据严重不均,此客户的订单数量大于总数的据库中数据严重不均,此客户的订单数量大于总数的10%10%。一进行这样的。一进行这样的查询就严重占用数据库资源,导致系统相应速度慢。查询就严重占用数据库资源,导致系统相应速度慢。解决的办法:这种行为都是现金交易根本不需要进行检查,查询的结果永解决的办法:这种行为都是现金交易根本不需要进行检查,查询的结果永远是空。程序绕过这个检查就行了。远是空。程序绕过这个检查
22、就行了。Step7:EXIST查询基本格式查询基本格式例:例:select count(*)from prm_adjustprice main,prm_adjustprice_b detail where main.cadjpriceid=detail.CADJPRICEID and main.cadjpriceid in(1,2)and exists(select*from bd_invmandoc where bd_invmandoc.SEALFLAG=N and detail.CINVENTORYID=bd_invmandoc.pk_invmandoc);不要将主表的其他条件写在子查询中
23、,这样可能不要将主表的其他条件写在子查询中,这样可能使外层查询没有条件而进行全表扫描。使外层查询没有条件而进行全表扫描。如果想按照子查询中的表作为驱动表进行查询,如果想按照子查询中的表作为驱动表进行查询,需要改造成需要改造成ININ子句。子句。Select.From Select.From 主表主表 where where 主表条件主表条件 and exists(Select*from and exists(Select*from 子表子表 where where 子表条件子表条件 and and 主表关联字段子表主表关联字段子表PK)PK)Step8:IN查询基本格式查询基本格式例:例:se
24、lect count(*)from prm_adjustprice main,prm_adjustprice_b detail where main.cadjpriceid=detail.CADJPRICEID and main.cadjpriceid in(1,2)and detail.CINVENTORYID in(select pk_invmandoc from bd_invmandoc where bd_invmandoc.SEALFLAG=N);如果不是想按照子查询中的表作为驱动表进行查如果不是想按照子查询中的表作为驱动表进行查询,建议改造成询,建议改造成EXISTEXIST子句,特
25、别是自查询存在子句,特别是自查询存在较多重复数据时。较多重复数据时。Select.From Select.From 主表主表 where where 主表条件主表条件 and and 主表关联字段主表关联字段 in(in(Select Select子表子表PK from PK from 子表子表 where where 子表条件子表条件)Step9:NOT IN尽量不要使用尽量不要使用NOT INNOT INNOT INNOT IN都可以改造成都可以改造成NOT EXISTSNOT EXISTSNOT INNOT IN中子查询如果对某个记录返回空,整个结果集中子查询如果对某个记录返回空,整个结
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Oracle 执行 计划
限制150内