在进行将oracle的数据同步到mysql的时候,由于数据量大导致使用kettle的全量同步比较慢,所以需要对这一过程进行优化。
优化方案:
1)从源头的表输入入手:通过设置表输入的多线程数据抽取,可提升数据的输入速度。
但是如果只是在kettle设置表输入的多线程数量的话,会导致数据重复。比如 select * from test ,起3个线程,就会查3遍,最后的数据就是3份。肯定不行,没达到优化的目的。因为source是oracle,利用oracle的特性: rownum 和函数: mod ,以及kettle的参数: Internal.Step.Unique.Count,Internal.Step.Unique.Number
例如:
select * from (SELECT test.*,rownum rn FROM test ) where mod(rn,${Internal.Step.Unique.Count}) = ${Internal.Step.Unique.Number}
解释说明:
- rownum 是oracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,意味着,如果排序字段或者数据有变化的话,rownum也会变(也就是跟物理数据没有对应关系,如果要对应关系的话,应该用rowid,但是rowid不是数字,而是类似 AAAR3sAAEAAAACXAAA 的编码),所以需要对rownum进行固化,所以将 SELECT test.*,rownum rn FROM test 作为子查询。
- mod 是oracle的取模运算函数,比如, mod(5,3) 意即 5%3=2 ,就是 5/3=1...2 中的2,也就是如果能获取到总线程数,以及当前线程数,取模,就可以对结果集进行拆分了。 mod(行号,总线程数)=当前线程序号。
- kettle 内置函数 ${Internal.Step.Unique.Count} 和${Internal.Step.Unique.Number} 分别代表线程总数和当前线程序号。
2)在插入更新处入手:设置插入/更新的线程数,提高数据的插入/更新速度。
在kettle开启插入/更新的多线程后,需要在对应的mysql数据库里对对应的表建立索引,不然会报错。当然,如果只是建立了索引但是没有开启多线程也可以提升速度,但是提升的还不够快。开启的线程也不是越多越好,因为到达了一定的瓶颈后再加线程后提升的效果并不是很大,所以具体是开启多少个线程要根据实际的配置确定。