又跟数据干上啦!现在手里(mssql2000下)的5000W数据要导入mysql,编程实现的。因为5000W数据的来源不同,所以存在用户名和Email重复的问题,进而每插入一条数据的前,都要和已插入的所有数据进行判断,并作出相应的操作。随着插入的数据的增多,导入开始变得慢下来了,最终导到20W的时候,终于内存溢出啦。不知道大家有没有什么好多建议,或者谁做过大数据的移植,还是这样有条件的移植 - - !大家指教一下,小雨十分感激。
附加:每次我都是手动执行这次导多少(5000)条,能不能让它自动导,点下开始就开始导,每次导入固定条数,然后继续导下多少条?并且可以随时
暂停下来,点继续就接着导入,因为数据大,所以一次次操作太累了,谢谢大家。HTTP Status 500 -type Exception reportmessagedescription The server encountered an internal error () that prevented it from fulfilling this request.exceptionjavax.servlet.ServletException: Servlet execution threw an exceptionroot causejava.lang.OutOfMemoryError: Java heap spacenote The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.
Apache Tomcat/6.0.16
附加:每次我都是手动执行这次导多少(5000)条,能不能让它自动导,点下开始就开始导,每次导入固定条数,然后继续导下多少条?并且可以随时
暂停下来,点继续就接着导入,因为数据大,所以一次次操作太累了,谢谢大家。HTTP Status 500 -type Exception reportmessagedescription The server encountered an internal error () that prevented it from fulfilling this request.exceptionjavax.servlet.ServletException: Servlet execution threw an exceptionroot causejava.lang.OutOfMemoryError: Java heap spacenote The full stack trace of the root cause is available in the Apache Tomcat/6.0.16 logs.
Apache Tomcat/6.0.16
能否建立个文件数据库先既根据英文a---z分,然后a之中又根据name的长度进行划分(长度1--10、11--15、16-20、20--XXX),,先把名字和Email进行分类(不知道名字是否包含中文,还有名字和Email是对应的还是每个都是独立项)写到文件中,这样的话就会减少很多比较次数,有点像中英文字典的模式,最后在将文件导入到数据库中(不知道能否导入,呵呵,否则这么大的数据量,任何机器都处理不了的)。
对于文件类型\XML型的原数据一定要论块解析入库.
现有数据5000W,存在于msssql2000数据库下,要导入到mysql下,数据的类型为用户注册的信息,由于来源于N个网站,所以存在用户名重复问题,为了解决这个问题,Email派上了用场,要求如下: 1、如果用户名、Email均不重复,则直接导入。
2、如果用户名重复,Email不重复,则把Email作为用户名。
2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
4、用户名、Email均重复,则跳过。
-------------------------------------------------------------------------------------------------------------------
按上述要求我进行了编程,开始Mysql下的表为空的,所以速度很快,1000条都用不了1秒,5000大概4秒左右,我每次导入的数据都是5000,但是随着导入数据的增多,速度会慢慢的慢下来,最后在导入进去20W后,导入下一个5000时,内存溢出,上次导入5000时耗时大约130多秒。求教csdn,不知道有什么好的办法,谢谢大家。如有任何不明白,我会随时回复。
谢谢大家,只能发100分帖子,要分的随时可以加。
为什么会越来越慢,而且内存溢出?我想是你为了解决用户名重复而做的判断吧。。可以试试wufongming说的,想全部插入,不用那么多判断,应该很快的。。然后写一存储过程或者几条sql,把用户名重复的去掉。
1 用户名和Email 这2个必须做索引,否则在检测重复时会有问题,谁让你的数据源不同呢!这属于合并数据哦2 使用批量insert 操作3 使用生产者消费者模式,用多线程4 不要用web方式,这东西肯定是客户端的应用程序只能说到这里了。再细的就得你自己考虑了。总之,批量insert和多线程肯定能加快速度。
PS: 我从网上查的.. 希望能用的上.
谢谢,myodbc,以前我导数据的时候用过,但是没有条件过滤的啊。我复杂的逻辑判断没法做,只适合做迁移。
这个的话。 你可以首先做下 过滤啊。 先把数据中达不到你要求的删除掉。用myodbc 做迁移 不行么?
选一个email(top 1)
选所有与此email相同的记录(好吧,我猜测这个数目不会很大)
代码处理这些记录,按照你的规则,导入到mysql当中。
从mssql当中删除这些记录。如果有100万记录都有相同的email,那就难做了。
其次,其他信息嘛,靠程序很难判断,比如真实姓名叫 范伟 的,100%是假的,但是叫 王亮 的,很可能50%是真的,代码怎么可能判断?
如果B表大于20万那就按邮件不同和有重复的再分2个表 一个C表保存邮件不重复(用户名肯定是重复) 一个D表保存余下的(邮件重复) 再将C表处理(2、如果用户名重复,Email不重复,则把Email作为用户名) D表按你的方法先处理 完后是直接插入A和C表
如果处理的C表插入A表有重复应该也不多(要A表中的用户名刚好和C表的邮件一样) 可以手动挑出来放进D表
我也只是个想法 没法测试
在一张表里的数据应该不会有重复项,所以只要用A表的数据和b的先比交
只是比较,有你说的那样的就处理其中一张表的,
这样的比较次数就应该是(A表中的数据量*b表中的数据量)
会比你那样做少了很多的比较次数,等这些都做好了
在导入到mysql
不知道可不可行,我是这么想的!
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import com.dts.pojo.User;
public class DtsDao {
private Connection conn_source = null;//源数据库连接
private Connection conn_target = null;//目标数据库连接
private boolean first_members = true;//首次查询members表 private static String insertMemberSql = "insert into uc_members (username,email,membersource) values (?,?,?)";//uc_members插入语句
private static String insertAttributesSql = "insert into uc_members_Attributes (zip,address,telphone,cellphone,realname,member_id) values(?,?,?,?,?,?)";//uc_members_Attributes插入语句// 总执行方法
public int dataOP(String targetDBName,String exeCount,String membersource) throws Exception{
conn_source = DBManager.getMssql2000Connection();
conn_target = DBManager.getMysqlConnection("ucenter"); Calendar calendar = Calendar.getInstance();
SimpleDateFormat format = new SimpleDateFormat ("yyyy/MM/dd/hh/mm/ss");
String sDate = format.format(calendar.getTime()); Date start = new Date(); System.out.println("================================开始时间"+sDate+"================================================");
int successCount = this.insertTarget(this.querySource(exeCount, conn_source),conn_source, conn_target, membersource); System.out.println("执行插入 "+successCount+" 条"); System.out.println("================================结束总耗时 "+(new Date().getTime()-start.getTime())/(1000)+" 秒,约为 "+(new Date().getTime()-start.getTime())/(1000*60)+" 分钟================================================="); this.release();
return successCount;
} //资源释放
public void release ()throws Exception
{
if(conn_target!=null){ conn_target.close();
} if(conn_source!=null){ conn_source.close();
}
}
//源数据查询
public List querySource(String exeCount,Connection con) throws Exception{ ResultSet sourceRs = null;
PreparedStatement ps = null;
Connection conn = null;
String sql = null;
List<User> sourceList = new ArrayList<User>(); if(exeCount!=null&&!exeCount.equals("")){ sql = "select top "+exeCount+" userid,username,useremail,address,zip,tel,cellphone,realname from users where flag=0 order by userid"; }else
{ sql = "select userid,username,useremail,address,zip,tel,cellphone,realname from users where flag=0 order by userid";
}
//建立源数据库连接
conn = con;
if(conn!=null)
{
ps = conn.prepareStatement(sql);
}
else{
System.out.println("mssql2000数据库连接失败");
}
//执行查询
sourceRs = ps.executeQuery(); while(sourceRs.next()){
User user = new User(); user.setUserid(sourceRs.getInt("userid")); user.setAddress(DtsDao.trimStr(sourceRs.getString("address")));
user.setCellphone(DtsDao.trimStr(sourceRs.getString("cellphone")));
user.setRealname(DtsDao.trimStr(sourceRs.getString("realname")));
user.setTel(DtsDao.trimStr(sourceRs.getString("tel")));
user.setUserEmail(DtsDao.trimStr(sourceRs.getString("useremail")));
user.setUserName(DtsDao.trimStr(sourceRs.getString("username")));
user.setZip(DtsDao.trimStr(sourceRs.getString("zip")));// if(!rs.getString("zip").equals("")&&rs.getString("zip")!=null)
// {
// String zipValue = rs.getString("zip").trim();// char [] zip = zipValue.toCharArray();// for(int i=0;i<zip.length;i++){
// if(!Character.isDigit(zip[i])){
// zipValue = "";
// }
// }
// user.setZip(zipValue);
// }
// else
// user.setZip(rs.getString("zip")); sourceList.add(user); }
System.out.println("此次查询并封装POJO "+sourceList.size()+" 条");
if(sourceRs!=null)
sourceRs.close();
if(ps!=null)
ps.close();
if(sourceList!=null)
return sourceList;
else
return null;
}
// 源数据标记更新为已操作(0未操作,1已操作)
public int updateSource(int updateid,Connection con) throws Exception{
PreparedStatement ps = null;
Connection conn = null;
int count = 0; //建立源数据库连接
conn = con; if(conn!=null)
{
ps = conn.prepareStatement("update users set flag=1 where userid=?");
ps.setInt(1,updateid);
}
//执行更新
count = ps.executeUpdate();
if(ps!=null)
ps.close();
return count;
} //会员(uc_members)查询
public List<User> queryTargetMem(Connection con) throws Exception{
ResultSet rsMembers = null; Connection conn = null;
List<User> memberList = new ArrayList<User>(); //建立源数据库连接
conn = con;
PreparedStatement ps = null;
if(conn!=null)
{
ps = conn.prepareStatement("select uid,username,email from uc_members");
// 执行查询
rsMembers = ps.executeQuery();
} while(rsMembers.next()){
User member = new User();
member.setUserid(rsMembers.getInt("uid"));
member.setUserEmail(rsMembers.getString("email"));
member.setUserName(rsMembers.getString("username")); memberList.add(member);
}
if(rsMembers!=null)
rsMembers.close();
if(ps!=null)
ps.close(); return memberList;
} //会员属性(uc_members_attributes)查询 public static List<User> queryTargetAtt(Connection con,int member_id) throws Exception{ ResultSet rsAttributes = null; Connection conn = null;
List<User> attributeList = new ArrayList<User>(); //建立源数据库连接
conn = con;
PreparedStatement ps = null; if(conn!=null)
{
ps = conn.prepareStatement("select zip,telphone,cellphone,address,realname from uc_members_attributes where member_id=?");
//执行查询
rsAttributes = ps.executeQuery();
}
while(rsAttributes.next()){
User attribute = new User();
attribute.setZip(rsAttributes.getString("zip"));
attribute.setTel(rsAttributes.getString("telphone"));
attribute.setCellphone(rsAttributes.getString("cellphone"));
attribute.setAddress(rsAttributes.getString("address"));
attribute.setRealname(rsAttributes.getString("realname")); attributeList.add(attribute);
}
if(rsAttributes!=null)
rsAttributes.close();
if(ps!=null)
ps.close();
return attributeList;
}
public int insertTarget(List sourceList,Connection conn_source,Connection conn_target,String membersource) throws Exception{ Connection conn_target_insert = null;
Connection conn_source_update = null;
int flaguc = 0;//插入uc_members条数
int flagatt = 0;//插入attributes条数
int update = 0;//更新mssql2000条数
int userNameRepeatCount = 0;//用户名重复条数
int emailRepeatCount = 0;//email重复条数
int member_id = 0;//重复id ResultSet tempRS = null;//为了获取插入的id List<User> memberList = null;//接收members表
List<User> attrbuteList = null;//接收attributes表 //建立源数据库连接
conn_target_insert = conn_target;
conn_target_insert.setAutoCommit(false);
//建立目标数据库连接
conn_source_update = conn_source;
conn_source_update.setAutoCommit(false); if(conn_target_insert!=null)
{ if(sourceList!=null){ for(int i=0;i<sourceList.size();i++){ User user = (User)sourceList.get(i);
//仅查询一次uc_members
if(first_members){
memberList = this.queryTargetMem(conn_target);
first_members = false;
} //1、如果目标表为空,即初始状态下。
if(memberList.size()==0){ DtsDao.insert(0, 0, tempRS, conn_target_insert, member_id, user, membersource, flaguc, flagatt, memberList, sourceList, i, userNameRepeatCount, emailRepeatCount, attrbuteList, conn_target);
}
else{
int userid_usernameback = 0;//用户名是否重复,0为不重复,大于0则重复。
int userid_emailback = 0;//email是否重复,0为不重复,大于0则重复。 userid_usernameback = DtsDao.isRepeatUserName(user.getUserName(),memberList);
userid_emailback = DtsDao.isRepeatEmail(user.getUserEmail(),memberList); //2、如果目标表不为空
DtsDao.insert(userid_usernameback, userid_emailback, tempRS, conn_target_insert, member_id, user, membersource, flaguc, flagatt, memberList, sourceList, i, userNameRepeatCount, emailRepeatCount, attrbuteList, conn_target);
}
// 更新mssql2000,标记为1,表示已操作。
update += this.updateSource(user.getUserid(), conn_source_update);
conn_source_update.commit();
} } } System.out.println("此次导入Members数据"+flaguc+"条。");
System.out.println("此次导入Attribute数据"+flagatt+"条");
System.out.println("已操作"+update+"条。");
System.out.println("此次导入共有重复用户名 "+userNameRepeatCount+" 条");
System.out.println("此次导入共有重复Email,或者用户名作为Email时,Email为空,忽略 "+emailRepeatCount+" 条"); return flaguc;
} //用户名是否重复
//判断username,0为不重复,>0为重复。
public static int isRepeatUserName(String userName,List targetList){ int isRepeat = 0; if(userName!=null&&!userName.equals("")){
for(int i=0;i<targetList.size();i++){
User member = (User)targetList.get(i);
if(member.getUserName().equalsIgnoreCase(userName)){
isRepeat= member.getUserid();
}
}
} return isRepeat;
}
// 判断email是否重复方法,0为不重复,>0为重复。
public static int isRepeatEmail(String email,List targetList){
int isRepeat = 0; if(email!=null&&!email.equals("")){
for(int i=0;i<targetList.size();i++){
User member = (User)targetList.get(i);
if(member.getUserEmail().equalsIgnoreCase(email)){
isRepeat= member.getUserid();
}
}
}
return isRepeat;
}
/**
Util for trim String
*/
public static String trimStr(String str)
{
if(!isNull(str))
return str.trim();
else
return str;
}
/**
Util for checking String that is null
*/
public static boolean isNull(String str)
{
if(str != null && !"".equals(str))
return false;
return true;
} //插入总方法
public static void insert(int userid_usernameback,int userid_emailback,ResultSet tempRS,Connection conn_target_insert,int member_id,User user,String membersource,int flaguc,int flagatt,List<User> memberList,List sourceList,int i,int userNameRepeatCount,int emailRepeatCount,List attrbuteList,Connection conn_target)throws Exception
{
PreparedStatement ps = null;
//1如果表为空,或者用户名和Email均不重复情况下
if(userid_emailback==0&&userid_usernameback==0){
DtsDao.insert_member_attribute(ps, conn_target_insert, user, membersource, flaguc, tempRS, member_id, flagatt, memberList,false);
}
//2、如果用户名重复 ,email不重复,则将email作为用户名。
if(userid_emailback==0&&userid_usernameback>0){
{
userNameRepeatCount++;
int isEmailEqualsUserName = 0;
isEmailEqualsUserName = DtsDao.isRepeatUserName(user.getUserEmail(),memberList);
if(user.getUserEmail()!=null&&!user.getUserEmail().equals(""))
{
//判断用做用户名的Email是否和用户名重复
if(isEmailEqualsUserName==0){
DtsDao.insert_member_attribute(ps, conn_target_insert, user, membersource, flaguc, tempRS, member_id, flagatt, memberList,true);
}
else if(isEmailEqualsUserName>0)
{
userNameRepeatCount++;
}
}else{
emailRepeatCount++;
} }
//3、如果用户名不同, email重复,即视为同一用户,则更新用户为空的属性。
if(userid_emailback>0&&userid_usernameback==0)
{
emailRepeatCount++;
attrbuteList = DtsDao.queryTargetAtt(conn_target,userid_emailback);
User attribute = (User) attrbuteList.get(0);
if(attribute.getZip()==null||attribute.getZip().equals("")){
DtsDao.update_attribute(ps, conn_target_insert, user, "zip", userid_emailback);
}
if(attribute.getAddress()==null||attribute.getAddress().equals("")){
DtsDao.update_attribute(ps, conn_target_insert, user, "address", userid_emailback);
}
if(attribute.getTel()==null||attribute.getTel().equals("")){
DtsDao.update_attribute(ps, conn_target_insert, user, "tel", userid_emailback);
}
if(attribute.getCellphone()==null||(attribute.getCellphone().equals(""))){
DtsDao.update_attribute(ps, conn_target_insert, user, "cellphone", userid_emailback);
}
if(attribute.getRealname()==null||attribute.getRealname().equals("")){
DtsDao.update_attribute(ps, conn_target_insert, user, "realname", userid_emailback);
}
ps.executeUpdate(); conn_target_insert.commit(); if(ps!=null)
ps.close();
}
//4、用户名、Email均重复
if(userid_emailback>0&&userid_usernameback>0){
emailRepeatCount++;
userNameRepeatCount++;
}
}
if(ps!=null)
ps.close();
}
//插入重用方法
public static void insert_member_attribute(PreparedStatement ps,Connection conn_target_insert,User user,String membersource,int flaguc,ResultSet tempRS,int member_id,int flagatt,List<User> memberList,boolean isRepeat) throws Exception{
ps = conn_target_insert.prepareStatement(insertMemberSql);
if(isRepeat)
{
ps.setString(1, user.getUserEmail());
}
else
{
ps.setString(1, user.getUserName());
} ps.setString(2, user.getUserEmail());
ps.setString(3, membersource); flaguc += ps.executeUpdate(); tempRS = ps.getGeneratedKeys();
if(tempRS.next())
member_id = tempRS.getInt(1);
if(tempRS!=null)
tempRS.close();
if(ps!=null)
ps.close(); ps = conn_target_insert.prepareStatement(insertAttributesSql);
ps.setString(1, user.getZip());
ps.setString(2, user.getAddress());
ps.setString(3, user.getTel());
ps.setString(4, user.getCellphone());
ps.setString(5, user.getRealname());
ps.setInt(6, member_id); flagatt += ps.executeUpdate(); conn_target_insert.commit();
memberList.add(user);
if(ps!=null)
ps.close(); }
//更新重用方法
public static void update_attribute(PreparedStatement ps,Connection conn_target_insert,User user,String updateColumnName,int userid_emailback) throws Exception{
ps = conn_target_insert.prepareStatement("update uc_members_Attributes set "+updateColumnName+"=? where member_id=?");
ps.setString(1,user.getRealname());
ps.setInt(2,userid_emailback);
}
}
不知道代码还有没有可以优化的地方,谢谢大家帮忙,再加分100.
导入到第11个2W的时候跑不动了 呵呵 关注中
先把那些唯一约束禁用
写SQL脚本导入数据
再删那些重复email的字段
再启用约束
这条语句mysql数据多了应该不行 可以弄个全局的arraylist<User>(); 每次插入mysql的用户就加到这个集合里 以后就不用去查mysql;我觉得首先还是要在mssql2000这边把数据分开 程序判断的只能是少量数据 如果最后有重复的数据 也可以在mysql那边删除
每个数据库都有命令导入数据库文件。
如果不行,用sql脚本是一个选择,如果你会写存储过程是最好的。
先录入数据,再用sql脚本筛选,效率比程序筛选高很多。
1、如果用户名、Email均不重复,则直接导入。
2、如果用户名重复,Email不重复,则把Email作为用户名。
2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
4、用户名、Email均重复,则跳过。
把重复的删除 然后把这个hash表传入 你的 写数据库 程序中循环这个hash 批量写入
不要把判断 和 插入数据库 放在一起
同意cool_scorpion 和wufongming 的说法。
我也觉得这些判断不应该在java端做,数据量这么大的情况下,用SP比较好。
而且楼主用了很多List<User>,这个是最占内存的,是否能想办法不要用List呢,
就算要用,也要在一开始就计算好,准备放多少object进去,比如每次1000个。
没仔细看程序,想确认一下这些个List最多可能放多少条数据呢?
DB里面有1万条,拿出来是不是就1万条呢?
DB里面20万条,拿出来就20万条了?如果是这样的话,溢出就是当然的了。
1、如果用户名、Email均不重复,则直接导入。
2、如果用户名重复,Email不重复,则把Email作为用户名。
2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
4、用户名、Email均重复,则跳过。 这个在mysql里可以做么?还是新手,望指教。
java零起点论坛,解决新手学习中遇到的困难,欢迎加入
也希望各位参与到论坛的管理中,现论坛开展当版主的q币活动
http://www.java07dian.com/thread-88-1-1.html
谢谢
针对这样的数据量,如果想在插入的同时还要做检索,数据库的操作肯定跟不上.
create table test(name varchar(100),email varchar(100),other1 varchar(100),other2 varchar(100))
insert into test select 'a','[email protected]','','test1'
insert into test select 'a','[email protected]','test2',''
insert into test select 'a1','[email protected]','test3',''
insert into test select 'a1','[email protected]','test3','test4'
insert into test select 'a1','[email protected]','','test4'
insert into test select 'b','[email protected]','',''--建立索引
create index test_name on test(name)
create index test_mail on test(email)
--临时表
select top 0 * into temp from test--插入有名字相同email不同的,用email代替名字
insert into temp
select email,email,other1,other2 from test a where exists(select 1 from test
where a.name=name and a.email<>email)
--插入其他的
insert into temp
select name,email,other1,other2 from test a where not exists(select 1 from test
where a.name=name and a.email<>email)--建立索引
create index test_name on temp(name)
create index test_mail on temp(email)--根据email建立一个最全的信息补充表
select email,max(other1) as other1,max(other2) as other2
into temp_other from temp a
where exists(select 1 from temp where email=a.email)
group by email
--建立索引
create index test_mail on temp_other(email)
--补充email相同的记录其他为空的信息
update temp set other1=b.other1 , other2=b.other2
from temp a inner join temp_other b
on a.email=b.email--补充后记录会有重复
select distinct name,email,other1,other2 from tempdrop table test
drop table temp
drop table temp_other
不费脑袋的办法:
10台普通pc做slaves,1台master,1台db服务器
master开10个线程维持到10个slaves的连接
master一次读取N条记录到内存,10个线程分别提取记录发送其连接的slave上排重
返回结果回馈给master,判断入库
5000W条没问题嘀
操作系统是什么?Windows还是Linux?
一定要用JAVA吗?
如果是表格式的数据并且是Linux系统的话建议用shell和awk处理完导入
5000W的数据量没有试过,但是一次20W很快的
把记录每20W条放在一个文件里,然后先在文件内判断重复,然后再文件间去重,最后一个一个文件导进去就好了
这个是我源表的表结构,数据都从这里来。windows系统
直接insert吧
加油
+---------------+-----------------------+------+-----+----------------------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------+------+-----+----------------------------------+----------------+
| uid | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| username | varchar(100) | NO | UNI | | |
| password | char(32) | NO | | b0a923be5f12a6458f1988a79c21608e | |
| email | char(150) | NO | | | |
| myid | char(30) | NO | | | |
| myidkey | char(16) | NO | | | |
| regip | char(15) | NO | | | |
| regdate | int(10) unsigned | NO | | 0 | |
| lastloginip | int(10) | NO | | 0 | |
| lastlogintime | int(10) unsigned | NO | | 0 | |
| salt | char(6) | NO | | 666666 | |
| membersource | varchar(50) | NO | | | |
+---------------+-----------------------+------+-----+----------------------------------+----------------+
12 rows in setmysql>
这个是目标表,用到插入的字段只有username,email,membersourcemysql> desc uc_members_attributes;
+-----------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------------------+------+-----+---------+----------------+
| att_id | mediumint(8) unsigned | NO | PRI | NULL | auto_increment |
| member_id | mediumint(8) | YES | | NULL | |
| zip | varchar(6) | YES | | NULL | |
| address | varchar(200) | YES | | NULL | |
| telphone | varchar(50) | YES | | | |
| cellphone | varchar(50) | YES | | NULL | |
| realname | varchar(50) | YES | | NULL | |
+-----------+-----------------------+------+-----+---------+----------------+
7 rows in set这个是会员的一些其他信息,我归结为属性表,添加对应的信息
问题具体描述:
现有数据5000W,存在于msssql2000数据库下,要导入到mysql下,数据的类型为用户注册的信息,由于来源于N个网站,所以存在用户名重复问题,为了解决这个问题,Email派上了用场,要求如下: 1、如果用户名、Email均不重复,则直接导入。
2、如果用户名重复,Email不重复,则把Email作为用户名。
2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
4、用户名、Email均重复,则跳过。
-------------------------------------------------------------------------------------------------------------------
按上述要求我进行了编程,开始Mysql下的表为空的,所以速度很快,1000条都用不了1秒,5000大概4秒左右,我每次导入的数据都是5000,但是随着导入数据的增多,速度会慢慢的慢下来,最后在导入进去20W后,导入下一个5000时,内存溢出,上次导入5000时耗时大约130多秒。求教 csdn,不知道有什么好的办法,谢谢大家。如有任何不明白,我会随时回复。
谢谢大家,只能发100分帖子,要分的随时可以加。