记一次SQL性能优化过程-索引并非多多益善

先给大家分享一套非常有用的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(很满意了)

最后建立组合索引,可以查看执行计划,免去了步骤,速度很快。

大致经过就是这样,有不足或补充请热情讨论

猜你喜欢

转载自blog.csdn.net/weixin_38316944/article/details/114377677