某项目用户反馈开发环境调用包中过程执行缓慢,需求协助优化
首先整体运行一次过程,确认单次执行耗时约30s。通过查询V$DMSQL_EXEC_TIME
视图,按照执行时间排序定位到耗时最多sql语句。
定位到耗时最多sql语句后,查询dba_source,在包体中追踪该语句位置,确认该语句属于过程中调用的另一过程。
进一步进入该过程理清逻辑,通过单独调试该过程,发现该过程在运行过程中需要首先查出一批数据,将这些数据以游标形式逐行扫描,作为查询条件拼接入sql进行查询。拼接后sql即为V$DMSQL_EXEC_TIME
中定位到的较长sql,sql共同特点是均需查询某张视图,且在过程中需传入不同条件循环查询数十次。
根据前文排查过程,主要耗时点在于查询视图的sql,该类sql单独运行耗时约0.2s,虽单次执行耗时不长,但在过程中需要多次循环查询,累积后耗时较大。
首先确认视图非物化视图,因此每一次查询过程中需现场执行视图定义语句。查看执行计划,可以留意到存在全表扫描。
追溯计划中涉及全表扫描的表,该部分查询来自于该视图A定义语句中,查询的另一个视图B
该视图B中存在大量or条件过滤语句,查询et,耗时最多操作符为SLCT2,与语句大量or条件对应。
至此确认优化方向,为降低语句中过多or条件带来的消耗
查询《dm8dba手册》,存在MAX_OPT_N_OR_BEXPS
参数用于配置能够参与优化的or分支个数,默认为7。在视图查询语句添加hint /*+MAX_OPT_N_OR_BEXPS(64)*/调大参与优化or分支个数,再次执行语句,耗时由0.2s缩短至0.02s左右。
重新查询ET可以看到SLCT2操作符耗时占比大幅下降。
对比执行计划可以看出,在添加hint后,优化器策略产生了变化,将or条件进行了展开,并且针对表的查询走了索引而非全表扫描,应当是对于查询条件的过滤条件策略变化后,优化器判定能够更好的利用到索引。
针对涉及大量or分支条件,且slct2操作符消耗较大的语句,可以尝试通过加hint的形式,适当调大MAX_OPT_N_OR_BEXPS参数,使得更多的or分支能够进行优化。
https://eco.dameng.com/
文章
阅读量
获赞