现在有61个文件夹,每个文件夹下面有365个txt文件,每个txt文件里面的数据格式都是固定的,大约每个文件有700行数据左右。用什么方法把这几千万条数据导入到数据库中效率会高点优先要求效率...
求大牛给出思路

解决方案 »

  1.   

    for(61个文件夹){
        for(365个文件){
            for(700行数据){
                // sql生成
                preparedstatment.addBatch();
            }
            // 一次连接数据库执行700条数据
            preparedstatment.executeBatch();
        }
    }
      

  2.   

    嗯,我想的是将这些文件都给颗粒化保存
    最小颗粒度至少是一个txt文件
    转化成json或者其他结构化语言保存?
    或者保存文件只是保存文件索引,然后每次请求都是根据索引请求文件内容。
    这样读取效率又低了。仅是个人想法,还请技术大牛点评
      

  3.   

    也许写个批处理,用Oracle自带的数据导入工具还更高效点。
      

  4.   

    你的txt内容不需要分类插入吗?就是内容会插入不同的表里。操作那个txt很简单。效率都差不多。他是一个文件一个文件的走,不需要考虑内存的问题。祝你成功!
      

  5.   

    是不是这么个思路,用批处理文件分解文件,然后用oracle自带的工具进行导入?
      

  6.   

    我会用java调用外部命令(dos下oracle导入txt的命令)方式导入所有文件,循环和3楼的方法差不多(只循环文件夹和每个文件夹下的文件)
      

  7.   

    话说在Action里面处理多线程我还米有试过呢求大蛇给意见
      

  8.   


    在Action里面处理多线程?!不推荐!对于此类大规模数据处理,建议的做法是,Web应用服务只负责接受请求(或者说指令)。另外写批处理程序负责批量的任务处理。这样结构灵活,且整体任务过程容易控制好。
    另外,看楼主的意思有点打算用多线程来处理了,顺便再给点关注点和建议吧。
    关注点:
    ◎ 批处理中比较讨厌的是重复发起任务,所以需要有标志控制;
    ◎ 既然是多线程,实际上就存在任务分配的问题,那么任务竞争与失败任务重做等也将成为问题;
    ◎ 多线程不是你启动线程数越多,速度就越快的,因为最终瓶颈点都在数据库的那张表上,所以线程数量太高将导致资源竞争激烈;
    ◎ 数据库表建议先删除或禁用所有索引,然后再执行批量插入,完毕后重建索引;
    建议:
    ◎ 建议批处理程序分为两个部分:1、任务分配者;2、任务控制器;2、工作线程。
    ◎ 任务分配者,负责将整体任务切分为子任务,比如按照目录和文件生成任务项,在你的例子里是61×365个任务项,将任务项批量写入任务表;可以按目录循环,每次写入365个任务(行);需要注意的是,这个动作每个整体任务来时只能做一次,否则就重复了;
    ◎ 任务控制器:负责从数据库抓取任务、维护任务标志位、线程池和线程调度,包括任务重试机制;
    ◎ 工作线程:负责根据任务控制器传递过来的任务项,打开指定文件,读取数据,然后用batch做数据提交,一次性完成一个txt的处理;
    ◎ 在这种模式下,可以随时监控总体任务进度,而且可以随时停止任务进行,并随时继续开始执行任务。最后就是线程池的线程数配置问题了,这个看服务器压力问题。如果你数据库非常强劲,但客户机不行。可以在多台机器上启动任务控制器。
      

  9.   

    数据格式都是固定的,为什么要用程序来做这事呢?不能用数据库的功能直接导么?另外,IO 操作用多线程等于白搭,因为 IO 操作的并发能力为 0,也就是说 IO 操作无法实现并发。
      

  10.   

    先构造成对应sql脚本文件呢?
    比如MYSQL,构造XXX.sql文件,再用导入
      

  11.   

    是oracle的话,搜索各个文件的路径名,写ctl文件,调用oracle的load命令,速度非常快!
      

  12.   

    既然不考虑方法,只是导入,就 sqlload 吧
      

  13.   

    这个我干过,不过效率很低MapReduce读取然后插入到一个MySQL表中,效率很低,关键是你的数据数目比较多,但是量不够大啊
    我当时的数据是几亿条数据,建议你用脚本调数据库load工具吧,吃不了多少内存。
      

  14.   


    我认为效率高点的还是格式化一下txt中的数据。。直接将txt的数据通过oracle命令映射插入表你那么多文件。。数据量那么大。。在应用中,无论怎么优化。。都没有直接使用命令行效率高。。直接和oracle性能挂钩。。少一个环节具体做法:例子:1. 创建测试表
    create table test_import
    (
    id int primary key,
    name varchar2(50),
    age int,
    test_null varchar2(20),
    re varchar2(100)
    );2. 创建imTable.ctl文件
    load data infile 'f:/test.txt' append into table test_import 
    trailing nullcols 
    (
    id terminated by ',', --字段
    name terminated by ',', --字段
    age terminated by ',', --字段
    re terminated by ',' --字段
    );3. 创建test.txt文件
    test.txt
    1,t1,20,第一个测试
    2,t2,25,第二个测试
    3,t3,22,第三个测试
    4,t4,30,第四个测试
    5,t5,28,第五个测试
    6,t6,23,第六个测试4. sqlplus中sql导入语句
    sqlldr 用户/密码@数据库实例名 control='f:/imTable.ctl' log='f:/log.txt' bad='f:/bad.txt' 5. 完成。。查看日志log.txt..
      

  15.   

    txt中给的数据都没有主键,所以打算先用程序处理下,将txt文件加上一列主键,
    然后用下楼上的方法。不知道这样速度是不是快一点。
    直接用程序导入数据库的确很慢,一千多万条数据大概得花5个小时,所以还是打算放弃这种方法。
      

  16.   

    对oracle不大了解 还望楼上的高手指导:sqlloader如何导入多个文件和如何解决主键问题
      

  17.   

    明白了,主键可以使用序列,指定某一列不在.csv数据文件中。
    可是有几千个文件,我不可能这样写:
    infile a.csv
    infile b.csv
    ...
    ...
    ...
    有米有更简单点的方法
      

  18.   

    用数据库自带的导入功能满足楼主的需求!对于写程序来操作一张表,用多线程都不能解决这个问题,涉及数据库的DML操作只能由一个线程在操作!
      

  19.   

    用sqllrd,大概4秒钟就能导进去了。
      

  20.   

    用sqlload可以导入文件,效率比较高。不过你那个文件比较多,可以用写程序获得目录下文件,然后调用拼装成命令行调用sqlload.
      

  21.   

    建议:写段代码,整合61*365个txt为365个txt(占用内存比较少,如果整合为61个响应时间会比较慢),然后可以写段代码自动调用365次sqlload直接写入数据表。(每次调用时,及时清理释放资源)
    另,如果需要排序调整可以再次编写程序调整。
      

  22.   

    python生成脚本
    使用sqlldr导入
      

  23.   

    sql server里面可以用 bulk insert