技术开发 频道

ETL的优化



    众所周知索引的作用在于查询时的效能提升。但这是以降低插入,修改,删除操作的性能为代价换来的。比如在插入数据的过程中,数据引擎既要将数据写入,又要同时维护索引,可能还要判断主键重复等情况,对性能有一定影响。
 
    理论上,在插入数据的过程中,如果目的数据表没有索引,不检查约束,不触发,不做事务记录是速度最快的。但一般情况下都难这样理想。所以我们考虑如果需要插入的数据量很大,可以在插入数据前先删除索引,插入操作完毕后再建立索引。这样避免了引擎在插入数据的同时维护索引,新建的索引也会更整齐连贯。

    经过实际测试,确认这种方法确实对性能有所提升。现在只要能排除锁表,并发等操作冲突的话基本没有什么优化的余地了。
    再看需要计算的部分。由于整个过程的逻辑比较复杂,数据量较大所以耗时较长。用掉了整个ETL过程 90% 时间。这部分理所当然的成为此次优化的重点。

    开发这个ETL程序的是个新手,以前做过ASP的WEB开发。很少用SQL脚本写逻辑程序。想当然的用游标实现了大部分逻辑运算。把SQL SERVER的表当成Record Set了!

    而且SELECT后面只跟“*”从来不写字段名,哪怕下面的计算只用到了这张表的一百个字段中的一个!这样的程序运行起来能快才怪!

    知道了原因就开始着手改,把大部分的游标操作用多张临时表之间的“INSTRT”、“UPDATE”代替,把 “SELECT *”换成 “SELECT Column1, Column2……”。

    这样一改程序的运行时间就由40分钟变成3分钟!可见游标的效率之低下! 

    其实游标的原理很简单,你对一个一千条数据的表做一个游标就等于 SELECT了一千次。而关系数据库的长项是对数据集进行操作。对单条数据库的操作还不如应用程序。把需要运算一千次单条数据的程序变成只需要运算几次数据集的程序。效率自然大大提升。 

    至此时间已经满足需求,我们也圆满的完成了此次优化任务。但做到这一步以后还有没有优化的余地呢?从技术角度看,我觉得还可以做些别的事情。比如单纯的逻辑运算,不和数据库交互的情况下考虑可以用程序实现。做好接口,传入需要计算的原始数据。传出结果直接存入数据库即可。在计算的过程中,可以并行做数据传输操作。又比如所有的临时表都用表变量,或者临时表干脆变成中间表这样就更省去了每次创建和删除的时间。
0
相关文章