今天在优化一个先人留下的sql语句时,发现有两个问题。在这些问题被解决后,SQL语句执行效率有了很大的提高。
首先介绍一下情况。
数据库是oracle。
我们使用的数据表有40+的字段。大概有4-5W条数据。
我们需要获取一个主管所负责的所有数据。
元sql是这样的:
select * from Opened_Ar where
customerid in
(select distinct customerid from Opened_Ar where
( sec not like 'SA%' and sec not like 'KR%')
and amt > 0 and sh_Of_Sales=&sh and ich != &sh
)
and bill_Date < to_date('2010-3-1','yyyy-MM-dd')
and (sec not like 'SA%' and sec not like 'KR%') and amt > 0
order by customerName1 desc,bill_Date desc
在尝试抓取一个只有49条记录的结果集时,竟然用时630s。崩溃了。
发现有两个问题:
- 使用了in关键字。虽然in对应的()内也只有几条数据,但是同样会影响速度。应该使用exists
- bill_date无法过滤掉大量的数据,应该放在最接近where的地方。可以过滤大量数据的条件放在距离where最远的地方。(因为sql语句是从下往上运行的)
最终的sql语句改为这样:
select * from Opened_Ar o1 where
bill_Date < to_date('2010-3-1','yyyy-MM-dd')
and (sec not like 'SA%' and sec not like 'KR%') and amt > 0
and exists
(select customerid from Opened_Ar o2 where ( o2.sec not like 'SA%' and o2.sec not like 'KR%') and o2.amt > 0 and o2.sh_Of_Sales=&sh and o2.ich != &sh and o2.customerid = o1.customerid
)
order by customerName1 desc,bill_Date desc
修改后,原来630s的时间,竟然缩减为不到一秒钟。非常好。以上是我的小修改。或许还有更好的方法。但这样已经可以达到我目前的需求了。