应用程序会调用数据库中一个应用程序包来取得一个返回结果,但是不知什么原因,程序包执行时间由原来的几秒变成了几十秒,导致应用程序运行缓慢,业务积压。
解决过程:
1.使用 10046 对该程序包进行跟踪,分析结果文件,定位到两个 SQL 语句很慢
语句1(30s):
Select count(*) from t1;
语句2(20s):
Select distinct t1.col1,t1.col2,t2.col3,t2.col4
from t1,t2
where t1.id=t2.id
and t1.name='cc'
order by t1.col5;
2.数据库优化
分析这两个语句的执行计划,发现都走了全表扫描,通过索引技术,性能大幅度提升,SQL1从30s提速到1s,SQL2从20s提升到1s。
3.需求与设计优化
对于上面的两个 SQL 语句,如果有一定的敏感度,这两个语句是很扎眼很奇怪的:
- SQL1为什么要统计条数,得到条数的真正目的是什么?
- SOL2中的distinct取唯一值是为啥,难道表有重复记录?distinct可是需要排序的。
- SOL2中的order by tl.col5;排序是T1表的col5字段,展现字段又没有这个字段,真的需要这个排序吗?
先来看SQL1:
经与业务人员分析,SQL1在代码中类似如下:
begin
select count(*) into v_cnt from t1;
if v_cnt>0
then ..A逻辑…
else
then ..B逻辑…
End;
可以看出,其需求其实是如果表中有记录则走A逻辑,如果表中无记录,则走B逻辑。
语句优化如下:
select count(*) from t1 where rownum=1;
至此,SQL1从1s提速到0.01s。
再来看SQL2:
发现确有大量的重复记录,而这些重复记录是因为源头程序有问题。
优化如下:
对源头程序进行把关改造,对现有数据进行去重,如此,就可以不用在 SQL 语句中 distinct 了。
而对于 order by,业务上根本没有这个需求,直接去掉。
至此,SQL2从1s提速到0.01s。