oracle view占资源,关于VIEW PUSHED PREDICATE的一个优化案例
根据这个案例需要的一些知识,后面会跟进关于外联结、视图合并、VIEW PUSHED PREDICATE的相关知识。
早上某数据库服务器CPU不断报警,应用系统管理员同时反馈应用响应明显变慢。登陆数据库主机查看,应用连接上来的几个进程占用了大量的CPU资源,造成CPU空闲率很低。登陆数据库查询,发现有不少buffer cache chains的等待,初步判断是应用上出现了某些性能糟糕的SQL语句。
通过进程捕获了几条耗资源的SQL语句,发现大部分都是类似同一条语句造成的。手工执行一下,需要2分多钟才能出结果。
捕获到的SQL语句如下:
SELECT *
FROM (SELECT DISTINCT e.n_event_id,
e.n_parent_id,
e.v_event_num,
em.n_req_type_1,
em.n_req_type_2,
em.v_title,
em.v_description,
e.n_priority,
cb.n_time_limit,
cb.n_status,
e.n_process_way,
e.n_maintaince_event_id,
e.v_maintaince_flag,
e.v_replacedevice_flag,
et.d_acbept_date,
et.d_finish_date,
et.v_exempt_status,
et.n_callback_status,
et.n_delay_time,
erpl.n_creator,
erpl.d_creation_date,
e.n_req_id,
el.v_res_notice_msg,
el.v_res_notice_email,
el.v_res_notice_im,
vd.v_valid_status,
vd.v_related_org_id,
e.n_dev_process_way,
e.v_over_time_reason,
e.v_confirm_person,
e.v_new_device_num
FROM tb_event e,
tb_event_related_person erpl,
vorg_department vd,
tb_callback cb,
tb_event_log el,
tb_event_marker em,
tb_event_track et
WHERE e.n_event_id = et.n_event_id(+)
AND e.n_event_id = em.n_event_id(+)
AND e.n_event_id = el.n_event_id(+)
AND e.n_event_id = cb.n_event_id(+)
AND erpl.n_dept_id = vd.recid(+)
AND e.n_event_id = erpl.n_event_id(+)
ORDER BY e.d_creation_date DESC)
WHERE rownum <= 40;
vorg_department为一个view,具体定义如下:
create or replace view vorg_department as
select d.recid,
r.v_valid_status,
d.v_related_org_id,
r.org_parent,
r.tree_no,
d.dept_kind,
d.dept_type,
d.dept_name,
d.status,
d.dept_code,
d.area_code,
d.dept_prof,
d.sort_num,
d.link_addr,
r.layer
from ORG_DEPARTMENT d, ORG_DEPRELATION r
where d.recid = r.org_child
and r.relation_type = 1
该语句的执行计划如下:
PLAN_TABLE_OUTPUT
———————————————————————————————————–
| Id | Operation | Name | Rows | Bytes|TempSpc|Cost|
———————————————————————————————————–
| 0 | SELECT STATEMENT | | 40| 15404| | 23M|
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 110M| 395G| | 23M|
|* 3 | SORT UNIQUE STOPKEY | | 110M| 27G| 58G| 11M|
| 4 | NESTED LOOPS OUTER | | 110M| 27G| | 2797|
|* 5 | HASH JOIN OUTER | | 1255K| 308M| 39M| 2797|
|* 6 | HASH JOIN OUTER | | 153K| 37M| 28M| 1873|
|* 7 | HASH JOIN OUTER | | 115K| 27M| 24M| 1384|
|* 8 | HASH JOIN OUTER | | 101K| 23M| 23M| 990|
|* 9 | HASH JOIN OUTER | | 100K| 22M| 17M| 571|
| 10 | TABLE ACCESS FULL | TB_EVENT | 77044| 16M| | 256|
| 11 | INDEX FAST FULL SCAN| IDX_EVENT_TRACK_N_E_ID| 100K| 491K| | 4|
| 12 | INDEX FAST FULL SCAN |IDX_TB_CALLBAK_E_ID | 75959| 296K| | 21|
| 13 | TABLE ACCESS FULL | TB_EVENT_MARKER | 3686| 18430| | 3|
|* 14 | INDEX FAST FULL SCAN | IDX_TB_EVENT_RP_DUP1 | 101K| 895K| | 4|
| 15 | INDEX FAST FULL SCAN |IDX_TB_EVENT_LOG_N_E_ID| 628K| 2455K| | 149|
| 16 | VIEW PUSHED PREDICATE | VORG_DEPARTMENT | 88| 1144 | | |
| 17 | NESTED LOOPS | | 1 | 15 | | 2|
|* 18 | INDEX UNIQUE SCAN | PK_DEPARTMENT | 1 | 6| | 1|
|* 19 | INDEX RANGE SCAN | ASSOCIATION8_FK | 1 | 9| | 1|
———————————————————————————————————–
首先了解了一下各表的统计信息情况和表的数据情况,统计信息都是最新的,除了tb_event_log表略微大点,有60多万数据外,其余表均10万左右或更小,执行计划里面的小表table full sacn和一些索引的access情况也并无严重问题。接下来关注表与表之间的关联顺序和方式。
继续分析这个执行计划,第四行评估出了一个超级大的结果集,找到这个结果集的产生方式,第16行引起了我的注意。VIEW PUSHED PREDICATE,在存在out join和view的情况下,CBO自动选择了谓词推进到了视图VORG_DEPARTMENT中以过滤更多的数据,也算无可厚非。但继续往上找,找到这个谓词的基数,第5行,发现评估出来的基数竟然有100多万行之多,而视图本身的结果集,只有不到3000行!
看来这是一个“愚蠢的”执行计划,CBO先选择视图之外的表做关联,tb_event虽然本身很小,但由于与其他表做多次外连接,因此最终得到一个庞大的基数,而拿着这个结果集推进到视图中,想想是多么恐怖的事情!
一般来说,大集合的结果集合并不适合进行PUSHED PREDICATE。如果只是少量,会起到比较好的效果。
既然知道了原因,那就尝试着去改变这个执行计划。Oracle提供了no_push_pred和push_pred来改变pushed predication行为,在上述语句中添加no_push_pred提示:
SELECT *
FROM (SELECT /*+ no_push_pred(vd) */ DISTINCT e.n_event_id,
e.n_parent_id,
e.v_event_num,
….
FROM tb_event e,
tb_event_related_person erpl,
vorg_department vd,
tb_callback cb,
tb_event_log el,
tb_event_marker em,
tb_event_track et
WHERE e.n_event_id = et.n_event_id(+)
AND e.n_event_id = em.n_event_id(+)
AND e.n_event_id = el.n_event_id(+)
AND e.n_event_id = cb.n_event_id(+)
AND erpl.n_dept_id = vd.recid(+)
AND e.n_event_id = erpl.n_event_id(+)
ORDER BY e.d_creation_date DESC)
WHERE rownum <= 40;
修改后的执行计划如下:
———————————————————————————————————–
| Id | Operation | Name | Rows | Bytes|TempSpc|Cost|
———————————————————————————————————–
| 0 | SELECT STATEMENT | | 40 | 11553| | 181K|
|* 1 | COUNT STOPKEY | | | | | |
| 2 | VIEW | | 1470K| 5398M| | 181K|
|* 3 | SORT UNIQUE STOPKEY | | 1470K| 370M| 765M| 92546|
|* 4 | HASH JOIN OUTER | | 1470K| 370M| 46M| 3546|
|* 5 | HASH JOIN OUTER | | 180K| 44M| 39M| 2499|
|* 6 | HASH JOIN OUTER | | 153K| 37M| 28M| 1873|
|* 7 | HASH JOIN OUTER | | 115K| 27M| 24M| 1384|
|* 8 | HASH JOIN OUTER | | 101K| 23M| 23M| 990|
|* 9 | HASH JOIN OUTER | | 100K| 22M| 17M| 571|
| 10 | TABLE ACCESS FULL | TB_EVENT | 77044| 16M| | 256|
| 11 | INDEX FAST FULL SCAN| IDX_EVENT_TRACK_N_E_ID | 100K| 491K| | 4|
| 12 | INDEX FAST FULL SCAN | IDX_TB_CALLBAK_E_ID | 75959| 296K| | 21|
| 13 | TABLE ACCESS FULL | TB_EVENT_MARKER | 3686| 18430| | 3|
|* 14 | INDEX FAST FULL SCAN | IDX_TB_EVENT_RP_DUP1 | 101K| 895K| | 4|
| 15 | VIEW | VORG_DEPARTMENT | 3355| 20130| | 3|
| 16 | NESTED LOOPS | | 3355| 50325| | 3|
|* 17 | INDEX FAST FULL SCAN | ASSOCIATION8_FK | 3356| 30204| | 3|
|* 18 | INDEX UNIQUE SCAN | PK_DEPARTMENT | 1| 6| | |
| 19 | INDEX FAST FULL SCAN | IDX_TB_EVENT_LOG_N_E_ID| 628K| 2455K| | 149|
———————————————————————————————————
调整后整个执行速度有了明显提升,15秒之内可以返回结果,可以看到view结果集与第六步产生的结果集进行hash join outer,然后得到的结果集合与最大的表tb_event_log再次进行hash join outer。当然这个执行计划可能还有完善的余地,需进一步根据数据情况调整表的关联顺序.
oracle view占资源,关于VIEW PUSHED PREDICATE的一个优化案例相关推荐
- VIEW PUSHED PREDICATE(谓词推入)引发的惨剧
帮网友调SQL http://www.itpub.net/forum.php?mod=viewthread&tid=1492997&extra=pageD1%3D&page=1 ...
- Oracle 学习笔记 11 -- 视图 (VIEW)
本次必须学习一个全新的概念-- 视图 (VIEW).在前面的笔记中曾提到过,数据对象包含:表.视图.序列.索引和同义词.前面的笔记都是对表的想剖析,那么本次笔记就对视图的世界进行深入的剖析. 视图是通 ...
- oracle expdp数据到txt,[20130727]ORACLE 12C使用expdp导出view数据.txt
[20130727]ORACLE 12C使用expdp导出view数据.txt 12C新特性里面可以定义试图,然后通过view当作表一样导出数据,然后导入数据库,自己做一个测试: 1.建立测试环境: ...
- 微信小程序中使view占满整个屏幕高度的实现方法
前言: 今天做小程序的时候,在项目中要用到一个view占满屏幕高度和宽度,然后再在这个view里放置其他元素的情况. 宽度很简单,直接设置width: 750rpx;或者width: 100%;就行. ...
- 谓词推进 PUSHED PREDICATE
UNION ALL PUSHED PREDICATE 谓词前推. 讲谓词推进 UNION ALL 的操作中 可以通过index 在union 之前 访问表 减少 union 和filter 的成本. ...
- 父View半透明,子View不透明
今天再封一个confirm控件的时候,出现了一个小的bug,是这样的:有一个view,这个父View上增加了一个View,父View的透明度我设置了alpha=0.6f,但是子View我没有设置,理想 ...
- oracle rac应急_Support for Oracle RAC 框架资源组故障
Support for Oracle RAC 框架资源组故障 本节介绍可能会影响 Support for Oracle RAC 框架资源组的一些问题. 在 Support for Oracle RAC ...
- 关于Presenting view controllers on detached view ...
为什么80%的码农都做不了架构师?>>> 使用模态跳转,Xcode有时候会出现 Presenting view controllers on detached view con ...
- android判断是否被点击方法,[Android]父View如何知道子View被点击了
需求是这样的: 封装了一个View,类似这样: image.png 1处的view是添加进来的,需要在点了1里面的某个view之后,把整个view隐藏掉. 因为1处的view是添加进来的,它里面的子v ...
最新文章
- CCF大数据专家委:2018年大数据发展趋势预测
- 求一个指定点对的路径上的最大边权或最小边权(转)
- 前端开发学习笔记 - 1. Node.JS安装笔记
- 应用系统日志采集解决方案
- flymcu无法打开串口_西门子1200与其他PLC/组态软件无线串口通讯(自由口)
- 用友 无法正确解析服务器,用友T3软件登陆软件时提示:“可能无法正确解析服务器名称或者相应的端口被禁用,请尝试输入服务器的IP地址”?...
- Tips:无法在Windows2012 R2+exchange2010中文版上安装SP3 RU8v2
- 算法:两条线段求交点
- 利率模型暗示美国股市是合理价值(仅做参考)
- C++ 中 ifstream读取txt文件内容
- Unity2D:简单人物纸娃娃换装实现(一) 服装的变换
- Java onvif协议,Java onvif协议通用协议获取rtsp地址
- ffplay播放器原理学习
- UU加速器——学术资源加速
- 深度神经网络与大数据分析技术之间,有什么相互作用?
- JZOJ1205. 帮助Bubu(2017.8B组)
- [渝粤教育] 中国地质大学 大学语文 复习题 (2)
- Safari无法验证网站身份
- 浮标水质监测站--河流湖泊水库现场水质自动监测的解决方案
- concurrent包