用perl做数据库迁移,从mssql到mysql(三)--v1.1版~多线程+handlersocket 从前边的程序的运行情况来看,程序是可以运行的,但速度太扯了,在读写1000w条之前速度还是可以的(大概2000条/秒左右),但过了1000w之后(变成400条/秒左右),当然这个与sql serv
用perl做数据库迁移,从mssql到mysql(三)--v1.1版~多线程+handlersocket
从前边的程序的运行情况来看,程序是可以运行的,但速度太扯了,在读写1000w条之前速度还是可以的(大概2000条/秒左右),但过了1000w之后(变成400条/秒左右),香港虚拟主机,当然这个与sql server读取,网络还有服务器等性能都是有关系的,但,这速度,不晓得有测试过的朋友受不受不了,我反正是受不了的,于是想了下,单线程慢,咱得改吧。改成多线程,多进程嘛。
另外再啰嗦一句,经小弟实测,改之后,效率真是快很多。。。。
不再啰嗦,直接上代码吧。
dbi; 3 use switch; 4 use strict; 5 use net::handlersocket; 6 use threads;::hires ;= ;= ;= ;=;= ;= 9999;=dbi->,$source_user_name,$source_user_psd); 19 #获取所有的用户表,不导有地理字段的表=$dbh->prepare(select name,object_id from sys.all_objects ao where type='u' and not exists(); 23 $sth->execute();#线程数。。。这个很纠结,小弟的服务器,在导的时候,美国服务器,5个线程以上,服务器会挂起~~~~=(not defined $argv[0])?5:$argv[0];=(not defined $argv[1])?3000:$argv[1];; 32 while (@data=$sth->fetchrow_array()) 33 { 34##测试时用($select_columns,$insert_columns,$column_count,$sort_column,$column_types); 37#获取某个表的列,并构建 查询,插入,列总数,列类型 38 ##输入参数如下: 39 ###data[0]:表名,data[1]:对像id 40 ##返回参数描述如下: 41 ###$select_columns:构建select的时候,列字符串 42 ###$insert_columns:构建insert的时候,列字符串。之所以要把这两分开,因为有些类型在select的时候,会用到列属性方法,例如geometry.stastext() 43 ###$column_count:列数,其实可以从@$column_types得到,但@$columns_types是后边加的,此参数也就没有去掉 44 ###$sort_column:用来排序的字段,因为总结了一下,一般第一个字段都是标识字段,主键,因此,这里只取的第一个字段 45 ###$columns_types:列的类型列表,一个数组。因为sql server里边的某些类型的值,在进mysql的时候,需要做处理,例如geometry($select_columns,$insert_columns,$column_count,$sort_column,$column_types)=get_columns($data[0],$data[1]); 48#查询结果。如果是导入失败,会返回false,否则为空= export_data_in ($select_columns,$insert_columns,$column_count,$sort_column,$data[0],$column_types); 51 52 }->disconnect; export_data_in 61 {($select_columns,$insert_columns,$columns_count,$sort_column,$table_name,$column_types) = @_;=0;=dbi->,$source_user_name,$source_user_psd);=); 67$sth_sc->execute();=$sth_sc->fetchrow_array();= 0;= $per_records - 1; 72while($begin_cnt @data_count[0]) 73 {;(my $count=1;$count$threads_cnt;$count++) 77 { 78##基本,香港空间,下边的sql语句成了本程序最大的性能瓶颈了。小弟的测试中,前1000w条数据还好,但,在1000w条之后,此sql语句的查询性能急剧下降,当然,小弟是在远程测试上边导的,(当然,我的表没分区的,有mssql优化经验的知道,表是可以分区的)=select * 81 from 82 ( 83 select $select_columns,row_number() over (order by $sort_column) as rownum 84 from $table_name 85 ) as t;;=threads->new(\&export_data, $table_name,$sql_select,$insert_columns,$columns_count,$column_types); 91push(@threads,$res0); 92$begin_cnt = $begin_cnt + $per_records; 93$end_cnt = $end_cnt + $per_records; 94 }(@threads) 97 { 98$_->join; 99 }100 }} export_data105 {=time;107my ($table_name,$sql_select,$insert_columns,$columns_count,$column_types)=@_;=dbi->,$source_user_name,$source_user_psd);=$dbh_mssql->prepare($sql_select);111$sth_select->execute();112$sth_select->{longtruncok}=1;=rand(3200);=;;118##还是改成fetchrow_arrayref(),小弟测试了下,这个的速度,真不是之前fetchrow_array能比的($select_data=$sth_select->fetchrow_arrayref())121 {122if($data_str ne )123 {;125 }=.,@{;128 129 },time-$starttime);131$starttime=time;132##测试的时候,查看数据的语句。($data_str ne )135 {;= { host => $aim_ip, port => $hs_port };= new net::handlersocket($args);= , );->get_error() if $res != 0;= $hs->execute_multi(eval($data_str));->get_error() if $hs->get_error() != 0;144$hs->close();145 };,time-$starttime);#这里啰嗦一下,也给大家展示一下我的结果 ^-^150 # exporting data t_p_areagroup_plate_userdiy_l;total:42758121;now:12825000151 # exporting data t_p_areagroup_plate_userdiy_l;total:42758121;now:12830000152 # exporting data t_p_areagroup_plate_userdiy_l;total:42758121;now:12835000153 # exporting data t_p_areagroup_plate_userdiy_l;total:42758121;now:12840000154 # exporting data t_p_areagroup_plate_userdiy_l;total:42758121;now:12845000155 # 读出时间18.9 seconds.156 # 写入时间1.3 seconds.157 # 读出时间23.3 seconds.158 # 写入时间1.4 seconds.159 # 读出时间23.7 seconds.160 # 写入时间1.1 seconds.161 # 读出时间25.6 seconds.162 # 写入时间0.6 seconds.163 # 读出时间25.6 seconds.164 # 写入时间0.9 seconds.} get_columns169 {;=select col.name,tp.name from sys.all_columns col172 inner join sys.types tp on col.system_type_id=tp.system_type_id and col.user_type_id=tp.user_type_id;=dbi->,$source_user_name,$source_user_psd);=$dbh2 -> prepare($sql);176$cols->execute();= ;= ;= 0;=;;;183while(@col= $cols->fetchrow_array())184 {185my ($col_name,$type_name)=@col;186@cols_types[$cols_count]=$type_name;187if($cols_count>0)188 {;;191 }{;195 })197 {;;200 }{;;205 }206$cols_count++;207 }208$dbh2->disconnect;209($cols_select,$cols_insert,$cols_count,$sort_column,\@cols_types);210 }211 212
调用方法(将运行结果放到out.log):
1 nohup perl export_data_muti_thread_v0.5.pl 10 5000 > out.log &
另外再啰嗦一句。。。cnblogs的回复真不多,哪怕是拍砖也好呀。别这么死气沉沉的。
posted on