用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本文来源gaodai#ma#com搞*!代#%^码网5) 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