有1T左右的文本数据,需要导入到Oracle。尝试了很多种方法,速度太慢了,而且有的导入方法有瓶颈,中途会产生大量错误,无法导入。
目前有一个比较稳定的导入方法是:
1、使用C++将数据写成 insert 语句,生成sql文件(2G一个文件),差不多900个文件。
2、使用sqlplus导入这些文件。目前导入了5个文件,将近花了30个小时,速度无法忍受。哪位大神提供一些方法,感激不尽!!!先给100分,解决以后,另外开4贴,一共送上500分

解决方案 »

  1.   

    如果不写成INSERT文件,可以直接把原数据文件按一定规则形成文件。
    使用Oracle自带的sqlldr导。
    这个试过没?
      

  2.   

    insert 的效率很慢的,还是推荐SQLLDR。
    SQLLDR还能支持并行处理,导数一般都用它。
      

  3.   

    使用SQLLDR或外部表吧,速度肯定会快很多。
      

  4.   

    必须的,用sqlldr,速度完全不一样的。当然,都上了T了,就别指望能快到光速了。。
      

  5.   

    可以用exp导成二进制方式,
    文本方式可以试一下sqlplus的spool方式
      

  6.   

    -- 我的思路是:-- Step 1: 将1T左右的文本数据分解成 100 个文本文件,并按顺序命名
    --         例如:tb001.txt、tb002.txt、tb003.txt、...、tb100.txt,
    --         并存放到5个(或更多)不同的磁盘中(这样并行导入的时候磁盘瓶颈相对较小)!-- Step 2: 在数据库中创建 5个(或更多)表空间,创建 100个名为 tb001、tb002、tb003、...、tb100的表,且平均分配到这5个表空间(其表的字段结构跟将要导入的目标表的字段结构一样)-- Step 3:用数据字典生成导入语句(控制文件及要导入的口令:
    -- 每个控制文件类似如下(共100个,所以:得用数据字典生成):load data
    infile "tb001.txt"
    append into table tb001
    fields terminated by ','
    (col1,
    col2,
    col3,
    ...,
    colN
    )-- 导入口令类似如下(共100条口令,可以加个并行 执行的参数或同时执行多个口令):
    sqlldr userName/password control=tb001.ctl log=D:\your_path\tb001.log bad=D:\your_path\tb001.bad errors=1000-- 最后:100个表的数据插入目标表(可以先将目标表的并行度加大,希望目标表是分区表更好,且先合理安排各分区表的数据文件的位置,以尽量避免IO瓶颈)insert into target_table select * from tb001;
    insert into target_table select * from tb002;
    ...
    insert into target_table select * from tb100;
      

  7.   


    多谢大家帮忙。sqlldr 会产生大量的错误,基本一半一半,也没搞明白原因。每一条消息5K 到 500K不等,排查了不少情况,但依然产生大量错误。这么大的信息量,也没办法一条一条去查了。好像有个内存映射的方法的,不知道哪位精通。
      

  8.   


    -- 错误可以忽略,然后sqlldr会将出错的数据记录到 .bad文件中(只是你导入前设置了这个参数),你也可以从日志文件中看到出错的一些信息!
      

  9.   

    -- errors=1000 这个参数表示在执行sqlldr口令时,最多忽略1000次错误,你可以设置得更高!
      

  10.   


    产生错误有可能是你的CTL文件写的不好,不可能是sqlldr的问题。
    就算是你用别的方法导进去了,将来一样还会出问题。
      

  11.   

    先研究下CTL,否则自己开发一个接近SQLLDR的,企业成本是否可以接受?除非你是爱好者
      

  12.   

    如果不借住第三方软件的话,用sqlldr确实比较好。
    但是使用sqlldr时注意日期、分隔符、换行等地方,是可以避免很多错误的。另外,文本文件也可以考虑根据sqlldr先行进行下处理,减少错误的发生。
    如果使用INSERT SQL的话,考虑多开并发、同时向多台ORACLE导入数据再合并的方式会快一些,但这个效率实在是高不到哪里去。
      

  13.   


    ctl文件写好,之后sqlldr导入的时候,打开并行,再加上direct,如果有时间转换的话把date_cache设置大一些,速度很快的。
      

  14.   

    sqlldr有很多优化的方法
    exp导出文件再导入
      

  15.   

    sqlldr是最好的选择,ETL工具都是使用sqlldr工具抽取数据的,选择direct和parallel的话,一分钟之内可以导入几千万
    就算100亿数据,大概10000分钟=7天不到,相信没有这么大的数据量吧。
      

  16.   

    1、sqlldr前,把ctl文件写好点
    2、把待插入的表的索引、主键、trigger之类的全drop掉,没有这些多余的操作,自然会加快很多的
    3、分开多个小文件,sqlldr直接导入
      

  17.   

    建议用第三方工具导会快的,比如DATASTAGE.