先给大家分享一套非常有用的SQL高级视频教程63集,高新程序员必备技能。大家扫码关注一下公众号 智程科技 ,回复 “sql优化” 即可免费领取哦
最近公司的一个项目,Oracle的CPU飙升,导致所有SQL执行缓慢,系统几近崩溃,废话不说来看排查经过吧
一、首先导出AWR报告
emm。。。红框处即为本次要优化的SQL执行情况
二、 优化思路:将最内层的数据集过滤精简
--这只是最内层的SQL,而实际的SQL是很复杂了,各种join,各种union,还有各种or,本章不谈这些 --VWTREEMENU 视图数据1万,DKTREEMENUTMP 表数据35万 select distinct OPT_NO from VWTREEMENU start with PGMID in (select PGM_ID from DKTREEMENUTMP where USR_ID = '?') connect by prior MEN_NO = PGM_ID
1.图凑合看吧,都是在内网操作的。首先,仅有USR_ID索引,执行时间2.7s。加了USR_ID索引执行还这么慢,很自然想到给PGM_ID建立索引。
2.增加PGM_ID索引,执行1.5s(进步了)
接着分析,表明表中存在不适当索引(唯一度不高),orcl便选择最优的执行计划,将这俩索引转为bitMap来执行,根据这俩索引的值再确认共同有的rowId,最后再通过ROWID回表提取符合条件的数据。
3.去掉USR_ID索引,执行时间0.25s(又进步了)
删除唯一度低的USR索引后速度已经很快了,但应该还有优化空间;orcl中索引保存的是字段值及值对应的rowId,当index range scan后,就会返回该block的rowId,再根据rowId直接去block上找数据。 表明还是需要根据rowId回表的数据块上查询数据。
4.建立PGM_ID和USR_ID的联合索引,执行时间0.09s(很满意了)
最后建立组合索引,可以查看执行计划,免去了步骤,速度很快。
大致经过就是这样,有不足或补充请热情讨论