又跟数据干上啦!现在手里(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

解决方案 »

  1.   

    对数据库不太熟悉:
    能否建立个文件数据库先既根据英文a---z分,然后a之中又根据name的长度进行划分(长度1--10、11--15、16-20、20--XXX),,先把名字和Email进行分类(不知道名字是否包含中文,还有名字和Email是对应的还是每个都是独立项)写到文件中,这样的话就会减少很多比较次数,有点像中英文字典的模式,最后在将文件导入到数据库中(不知道能否导入,呵呵,否则这么大的数据量,任何机器都处理不了的)。
      

  2.   

    我专门做数据入库的,每次都是千万级数据,不过我用的是Oracle,最后总结一句话:
       对于文件类型\XML型的原数据一定要论块解析入库.
      

  3.   

    先全部插入,再在mysql上判断删除重复的。
      

  4.   

    问题具体描述:
         现有数据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分帖子,要分的随时可以加。
      

  5.   


    为什么会越来越慢,而且内存溢出?我想是你为了解决用户名重复而做的判断吧。。可以试试wufongming说的,想全部插入,不用那么多判断,应该很快的。。然后写一存储过程或者几条sql,把用户名重复的去掉。
      

  6.   

    麻烦哦!5000w 不是个小数目哦,特别是还有重复的检测问题
    1 用户名和Email 这2个必须做索引,否则在检测重复时会有问题,谁让你的数据源不同呢!这属于合并数据哦2 使用批量insert 操作3 使用生产者消费者模式,用多线程4 不要用web方式,这东西肯定是客户端的应用程序只能说到这里了。再细的就得你自己考虑了。总之,批量insert和多线程肯定能加快速度。
      

  7.   

    写一个存储过程里再写游标,存储过程里写个数量判断的语句,一次设定插多少,在游标里写个Where语句做重复检测。
      

  8.   

    mysql 有一个 专门支持 ODBC的驱动。名字叫做 MYODBC。也以提供mysql的odbc支持。装了之后 在 sql2000下直接把数据导成mysql形式的。。 
    PS: 我从网上查的.. 希望能用的上.
      

  9.   


    谢谢,myodbc,以前我导数据的时候用过,但是没有条件过滤的啊。我复杂的逻辑判断没法做,只适合做迁移。
      

  10.   

    你的数据是不是来源于文件,还是其他数据库,如果是文件,用 内存映射文件 来解决,参考 java.nio.*包
      

  11.   


    这个的话。 你可以首先做下 过滤啊。  先把数据中达不到你要求的删除掉。用myodbc 做迁移 不行么?
      

  12.   

    先在mssql里处理啊
    选一个email(top 1)
    选所有与此email相同的记录(好吧,我猜测这个数目不会很大)
    代码处理这些记录,按照你的规则,导入到mysql当中。
    从mssql当中删除这些记录。如果有100万记录都有相同的email,那就难做了。
      

  13.   

    首先,只有email是真实的,因为很多网站注册要email可用。
    其次,其他信息嘛,靠程序很难判断,比如真实姓名叫 范伟 的,100%是假的,但是叫 王亮 的,很可能50%是真的,代码怎么可能判断?
      

  14.   

    能不能先在mssql2000中先建2个结构相同的表 一个保存用户名和邮件都不同的数据(A)  另一个保存剩余的数据(B) 然后如果B表的数据不足20万就按你原来的方法先处理 完后剩余的A表就直接插入 
    如果B表大于20万那就按邮件不同和有重复的再分2个表  一个C表保存邮件不重复(用户名肯定是重复) 一个D表保存余下的(邮件重复) 再将C表处理(2、如果用户名重复,Email不重复,则把Email作为用户名) D表按你的方法先处理 完后是直接插入A和C表 
      

  15.   

    您好,西木,你的方法我明白,但是我现在手里仅有405,即使这中方法可行,那么后面再来的数据呢,又在A表中。然后这个A的数据再放入mysql下,不敢保,或者说一定还会有重复的啊,如果一次行查处5000W数据的重复与否,我估计数据库也承受不来的。您说呢?
      

  16.   

    估计得建个测试库做 先建2个索引 再distinct 邮件  在邮件没重复的表中再distinct 用户名 得到A表 看数据库能不能承受
    如果处理的C表插入A表有重复应该也不多(要A表中的用户名刚好和C表的邮件一样) 可以手动挑出来放进D表 
    我也只是个想法 没法测试 
      

  17.   

    我觉得你在导入到mysql之前可以将那些数据先进行比较,
    在一张表里的数据应该不会有重复项,所以只要用A表的数据和b的先比交
    只是比较,有你说的那样的就处理其中一张表的,
    这样的比较次数就应该是(A表中的数据量*b表中的数据量)
    会比你那样做少了很多的比较次数,等这些都做好了
    在导入到mysql
    不知道可不可行,我是这么想的!
      

  18.   

    package com.dts.dao;import java.sql.*;
    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;
    }
      

  19.   

    //目标数据库导入
    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.
      

  20.   

    我曾经测试过2W条数据一次导入到mysql
    导入到第11个2W的时候跑不动了  呵呵  关注中
      

  21.   

    我只能给个建议
    先把那些唯一约束禁用
    写SQL脚本导入数据
    再删那些重复email的字段
    再启用约束
      

  22.   

     memberList = this.queryTargetMem(conn_target);
    这条语句mysql数据多了应该不行 可以弄个全局的arraylist<User>(); 每次插入mysql的用户就加到这个集合里 以后就不用去查mysql;我觉得首先还是要在mssql2000这边把数据分开 程序判断的只能是少量数据 如果最后有重复的数据 也可以在mysql那边删除
      

  23.   

    不知道你的数据源是什么?
    每个数据库都有命令导入数据库文件。
    如果不行,用sql脚本是一个选择,如果你会写存储过程是最好的。
    先录入数据,再用sql脚本筛选,效率比程序筛选高很多。
      

  24.   

    还是满足不了我这个条件啊!
    1、如果用户名、Email均不重复,则直接导入。
        2、如果用户名重复,Email不重复,则把Email作为用户名。
            2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
        3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
        4、用户名、Email均重复,则跳过。 
      

  25.   

     先把数据导入一个hash表中 然后在这个hash表中判断
     把重复的删除  然后把这个hash表传入 你的 写数据库 程序中循环这个hash 批量写入
     不要把判断 和 插入数据库 放在一起 
      

  26.   

    我就是这么做的啊,就查询了一次mysql。
      

  27.   

    数据源是mssql。不是简单的迁移,还有数据的合并、过滤的。
      

  28.   


    同意cool_scorpion 和wufongming 的说法。
    我也觉得这些判断不应该在java端做,数据量这么大的情况下,用SP比较好。
    而且楼主用了很多List<User>,这个是最占内存的,是否能想办法不要用List呢,
    就算要用,也要在一开始就计算好,准备放多少object进去,比如每次1000个。
    没仔细看程序,想确认一下这些个List最多可能放多少条数据呢?
    DB里面有1万条,拿出来是不是就1万条呢?
    DB里面20万条,拿出来就20万条了?如果是这样的话,溢出就是当然的了。
      

  29.   

    是啊,所以随着导入数据的增多,早晚会溢出的。一起导入过去 我15楼的条件
    1、如果用户名、Email均不重复,则直接导入。
        2、如果用户名重复,Email不重复,则把Email作为用户名。
            2-1、此时作为用户名的Email,同样要和已导入的数据的用户名进行一次判断是否重复。
        3、用户名不重复,Email重复,则认为是一个用户,如果用户信息存在空值的字段,则更新空值字段为新数据的字段信息。
        4、用户名、Email均重复,则跳过。 这个在mysql里可以做么?还是新手,望指教。
      

  30.   

    44才知道!mysql能支持多少数据量?
      

  31.   

    同意这个观点,用批量插入的方法,插入完后就会释放内存,一次插那么多肯定不行,用多线程控制程序的开始和停止www.java07dian.com
    java零起点论坛,解决新手学习中遇到的困难,欢迎加入
    也希望各位参与到论坛的管理中,现论坛开展当版主的q币活动
    http://www.java07dian.com/thread-88-1-1.html
    谢谢
      

  32.   

    想办法把mssql中的重复数据先过滤掉,按照你说的过滤条件,将不符合要求的数据过滤掉,这些操作在mssql中应该能够完成...
    针对这样的数据量,如果想在插入的同时还要做检索,数据库的操作肯定跟不上.
      

  33.   

    测试一下这个例子--测试环境,比如name,email,other1和other2代表其他信息
    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
      

  34.   


    不费脑袋的办法:
    10台普通pc做slaves,1台master,1台db服务器
    master开10个线程维持到10个slaves的连接
    master一次读取N条记录到内存,10个线程分别提取记录发送其连接的slave上排重
    返回结果回馈给master,判断入库
    5000W条没问题嘀
      

  35.   

    就是说,你可以把email重复的数据直接删掉了
      

  36.   

    你的数据格式是什么样子的啊?是SQL语句还是类似于表格的?
    操作系统是什么?Windows还是Linux?
    一定要用JAVA吗?
    如果是表格式的数据并且是Linux系统的话建议用shell和awk处理完导入
    5000W的数据量没有试过,但是一次20W很快的
    把记录每20W条放在一个文件里,然后先在文件内判断重复,然后再文件间去重,最后一个一个文件导进去就好了
      

  37.   

        if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[users]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[users] GO CREATE TABLE [dbo].[users] ( [userid] [int] IDENTITY (1, 1) NOT NULL , [username] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL , [useremail] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL , [tel] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL , [cellphone] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL , [address] [varchar] (1000) COLLATE Chinese_PRC_CI_AS NULL , [zip] [char] (6) COLLATE Chinese_PRC_CI_AS NULL , [realname] [varchar] (200) COLLATE Chinese_PRC_CI_AS NULL , [flag] [int] NOT NULL ) ON [PRIMARY] GO
    这个是我源表的表结构,数据都从这里来。windows系统
      

  38.   

    没办法了  看来只有用我的办法帮你了
    直接insert吧
    加油
      

  39.   

    mysql> desc uc_members;
    +---------------+-----------------------+------+-----+----------------------------------+----------------+
    | 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这个是会员的一些其他信息,我归结为属性表,添加对应的信息
      

  40.   


    问题具体描述:
        现有数据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分帖子,要分的随时可以加。