这个专题讲一些日常运维的异常处理 今天讲一个SQL 语句,他有很多标量子查询,其中有的是使用了函数 ## 1. 现象 开发人员反映有条语句非常慢 [image:104 size:orig] ## 2. 原因查找 ### 2.1 查看整体执行计划 [image:105 size:orig] 可以看出语句非常简单,由于 from后的表没有任何where条件 估算的是一行,实际看下了下有9000+的数据,单独查询1s不到 总体执行下来需要10分钟 接下来我们需要知道慢在哪里 ### 2.2 找出慢的地方 这里我们采用笨的方法,注释掉其他的标量子查询只用其中一个 这时我们可以找出**DCWIP.GET_WIRETYPE(CONTROL_LOT)**这段占用了绝大多数的时间 到这里我们知道可能的原因是该语句循环执行了该函数近10000次导致 这里我们通过查看awr报告也证明了这点 ### 2.3 优化函数 这时我们打开该函数,发现非常简单,里面有2个语句,将参数带进去,我们查看执行计划 [image:106 size:orig] 可以看到其中有一个全表扫描,数据量3W比左右,执行时间0.03s 这里执行不频繁还好,如执行太多则会造成CPU大量消耗 接下来我们优化这个语句 我们有2种栏位选择 bdg_device 和 bdg_diepart 我们使用group by 查看 where栏位的分布情况 发现diepart 分布比较唯一 ``` select BDG_DEVICE,count(*) from FWASSY.FWCATNS_AS_BONDINGDIAGRAM t group by BDG_DEVICE order by count(*) desc ``` [image:107 size:orig] 这时我们在该栏位建索引 ``` create index fwassy.BONDINGDIAGRAM_BDG_DEVICE on fwassy.FWCATNS_AS_BONDINGDIAGRAM(BDG_DEVICE) ``` 之后看执行计划已经走索引了 [image:108 size:orig] ##3. 优化成果: 由于这是一个报表,还有其他语句,但是总体时间从原来的40分钟下降到15分钟 达到预期效果