SQL优化三板斧:精简之道、驱动为王、集合为本
对于这次的优化,我并没有抱什么希望,因为这仅仅是常规性的精简,还没有深入到代码内部.或者说,这还仅仅是规范性改写. 果真,执行仍然需要耗时4分多钟,但是,这次的精简并不是没有任何收益.因为当往下钻取时,速度非常快,钻取完6625条记录不到10S. 第二板斧:披荆斩棘第二天一上班,就开始接着昨天的节奏继续优化. SQL的精简并没有为快速返回带来任何收益,我决定看下执行计划,尝试着从执行计划中得到更多的信息.果真,F5后看到的执行计划中,一个VIEW的COST犹如“鹤立鸡群”,特别的扎眼: 从执行计划看,Oracle对这个视图做了传统的处理,没有合并,也没有谓词推入.所以视图中的表基本上都是table access full.此时,突然想起在当时统计表对象的时候,记得只有一个视图,而在昨天在精简B类子查询的时候,也出现过一个视图.那这两个视图应该是同一个了.而昨天B类子查询的速度是非常快的. 我赶紧将执行计划定位到了B类子查询,如下: 原来如此,在B类子查询中,该视图被merge了. 受此启发,我也计划将主查询中的VIEW通过HINT进行MERGE,但是HINT似乎并不生效,始终都无法改变现有的执行计划.无奈之际,只有深入SQL,实地窥探这个VIEW到底“何德何能”,会让ORACLE优化器如此“死心塌地”的“维持原判”. 从上图中可以看出,该视图与A类子查询进行了关联,而事实上,B类子查询就是该视图与A类子查询关联的结果呀.怎么在这里又要临时关联呢?难道昨天做精简的时候还存在漏网之鱼? 再看代码: 原来这里需要获取该视图的两个字段,而在B类子查询中,我们只获取了SHIPMENT_GID一个字段.那是否可以直接在B类子查询中加一个字段呢? 我们再来看看B类子查询的代码逻辑: 在这里,我们获取了SHIPMENT_GID字段,并对该字段通过DISTINCT去除了重复值.这样做的目的在于,在后面调用该子查询时,以该子查询为驱动表,驱动关联其他表对象.因为子查询的结果集很小,而被关联的表对象都是千万上亿级别的. 很显然,如果我们在B类子查询中增加ORDER_RELEASE_GID字段,就会影响到SHIPMENT_GID的唯一性,这样,在后续的关联查询中,就不能直接用B类子查询驱动关联.这会直接破坏掉已经建立好的驱动关系. 既然增加字段之路行不通,那就尝试着再增加一个WITH子查询,代码如下: 与此同时,对访问该视图的代码也进行了适应性的修改,修改后的脚本如下:
(编辑:焦作站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |