通过【Oracle移行到Sqlserver完美解决案】①Sqlserver内存溢出,内存溢出的问题解决了,通过insert..select的方式,基本可以解决移行的问题。但是作为一个要拿到客户现场使用的工具,执行的时间是我们必须要考虑的,接下来把改善过程,时间差异,跟大家说下,有问题,建议,给我留言啊。
背景:
操作log表,数据600多万件,字段很多,占内存3G多,从oracle中将操作log表中的数据,导入到Sqlserver的操作log表。服务器内存16G
分析:
insert..select的方式,我们单独执行select部分,发现主要花费时间的地方是select,那我们想如何能提高从oracle取数据到sqlserver的时间呢。
我们想到了bcp,将oracle的数据通过bcp导入到txt文件中,再使用bulk insert将txt文件插入到sqlserver(bcp,bulk insert的使用方法,下面会提到)。那么bcp和bulk insert又是谁更占用时间呢,发现是bcp。接下来我们想到内存溢出时,bcp和select方式我们曾经做过记录,比较如下,所以我们决定使用bcp+insert的方式来实现
select方式:
insert LDBTLOGT select * from OracleLink..LDBTLOGT 9小时左右,内存溢出,36万件数据被插入
bcp方式:每10万件导出一次
10万件导入 30分后完成
20万件导入 60分钟左右,内存溢出
具体实现案:
这里是用powershell来做的工具,我只是把主要的点写下来,对于多表可以自动生成$runSql语句,然后循环调用执行
--1.查询SQL语句,
--这里要注意使用OPENQUERY,后面单引号语句使用的是oracle语法,不是sqlerver
$runSql = SELECT * FROM OPENQUERY(OracleLink,'select Oracle字段 FROM (SELECT Oracle字段,rownum num FROM LDBTSMP) t2 WHERE t2.num between $BEGINNUM and $ENDNUM')
--2.通过bcp将$runSql语句的数据保存到$dataFile文件
--同样导出成文件,就会有编码的问题,例如:我遇到编码不对,TiO?=>TiO?,
BCP $runSql queryout $dataFile -f $frmFile -T -S $ServerInstance -U lab -P lab
--3.通过buld insert 将文件中的数据,插入到sqlserver
$insSql = "BULK INSERT " + $viewName + " FROM N'" +$dataFile + "' WITH ( FORMATFILE = N'"+ $frmFile +"');"
--4.执行$insSql语句
Invoke-Sqlcmd -Query $insSql -ServerInstance $ServerInstance -Database $sqlServerDbName -Username "lab" -Password "lab"
时间统计
对于LDBTLOGT表,移行的整个过程,花费32小时。看到这个时间是否崩溃了,我的天啊。
客户的回馈是,你让导入人员到客户现场,工具执行后,2天时间干等着吗。客户就是上帝,接下来我们又会如何改善呢,敬请期待。
反思
花费时间那么长,我认为还是oracle和sqlserver之间的数据类型转化占用的大量的时间。我们如何能避免类型数据的转化,你如果使用了sqlserver的provider创建dblink来查询,这个无法避免。
真是伤透脑筋。可以跟大家透露下,最终3小时搞定,敬请期待。
索引:
【Oracle移行到Sqlserver完美解决案】①Sqlserver内存溢出
【Oracle移行到Sqlserver完美解决案】②内存溢出时查看SQL