今天同事反馈ETL数据抽取很慢,并且用的DBLINK来做数据抽取,慢到什么程度呢?大概要执行2~3小时,很久没搞过Oracle了,很多技能都已经生疏了,抱着试试完的心态,决定帮这个忙;后来经过优化,运行速度到了2分钟级别,其实还有优化的空间,算了,就这样吧。现在讲讲相关优化过程。
1、了解背景情况
让厂家找到相关语句,一看却是个UPDATE语句,再看SQL语法,是个带.的表和不带.的表,根本不是什么DBLINK,就是同一个数据库上的不同用户而已。
既然慢,那就慢慢看语句吧,语句不复杂,就是从一张表根据条件更新到另一张表
UPDATE语句比较烦人,一般情况下我都会把语句改写成SELECT语句
2、查看执行计划
对改写后的语句进行执行,并且查看执行计划,乖乖,都是FULL TABLE SCAN。
3、对表和索引做分析
接下来是分析表和索引,看什么呢?看表结构看分区看索引看表数据看索引分布
看表结构主要看ALL_TABLES,ALL_INDEXES,ALL_IND_COLUMNS,ALL_TAB_PARTITIONS
其实看那么多,不一定有用,直接在pl/sql developer里面view一下表结构,再看ALL_TABLES和ALL_INDEXES就OK了。
通过ALL_TABLES结果发现外层表有50万条记录,内层表有2亿条记录,且按SJSJ做时间分区,每个分区计算下来是500万记录
通过ALL_INDEX,发现内层表的YHBH,JLDBH,ZCBH都是单一索引,且键值非常多,非常适合做索引列,YHBH,JLDBH,ZCBH这三列随便用哪个索引都是差不多;再看外层表,发现该表空空如也,什么索引都没有。
在WHERE条件中,发现用到了分区条件,和内层表的三个索引列
4、进行优化
通过以上分析,可以知道在外层表上随便建一个索引,应该就会取得较好的效果。
CREATE INDEXAAA ON dl_jlddl_r_sjd(YHBH)
5、评估效果
创建完索引后,运行脚本,120秒足以,再看执行计划也使用到了索引