前提:目的是实现一个程序,能够实现某些表在满足某些事件的时候能够实现数据导出,生成文件(.CSV结构),然后把文件扔给下一个程序去处理.
实现方式: 使用ADO Connection 建立连接读表,将结果集赋给_Recordset(ADO DATASET) 然后通过循环读取,将值写入到带缓冲区的TFileStream(流中)
//连接字符串 
sConnectStr := 'Provider = OraOLEDB.Oracle.1;'
      + 'Persist Security Info = True;FetchSize = ' + IntToStr(iFetchSize) + ';'
      + 'Data Source = ''' + Trim(sAlias) + ''';'
      + 'User ID = ''' + Trim(sUserName) + ''';'
      + 'Password =''' + Trim(sPassword) + '''';
//结果集缓存在服务器
TConnection.CursorLocation:=adUseServer;
RS:=TConnection.Execute(Self.Fsql,varRecordCount,adOpenForwardOnly);
//建立缓冲区
RS.CacheSize := iCacheSize;
 for 循环读取记录写入到文件流中    目前的性能如下
   数据库服务器 16CPU + 32G内存, 程序运行机器(4 CPU ,2G)内存
因为是串行操作,程序只能使用到1个CPU,(该CPU的占用率为100%),导出速率为 3.2M/S!
目前还想提高下性能,因为这是一个大公司的数据中心主动推送服务,每日推送数据量可能会在5G-10G左右!
瓶颈: 文件流写入,如果是循环写入的话,速度在个人PC上可以到10M/S,因此这块不是问题,我们怀疑应该是 ADO取结果集这块会慢,数据库是缓存在服务器上的,
服务器跟应用程序的连接(100MB),同一局域网!缓存到本地,本地机器的内存不够扛,并且缓存到本地的性能经测试跟缓存到服务器上的性能差不多多远!当然可行的方案有很多,第一个文件导出并发操作(有4个CPU,就可以开4个线程进行导)!
ORACLE自己使用的imp/exp工具的速度非常快,在我现在环境下几乎就是文件拷贝速度(16M/S)!
不知道各位有没有什么好的方法!

解决方案 »

  1. 能否把程序发布在服务器上,然后在存储过程中使用文件操作来解决?
    又或者,你的程序放在哪里都可以,但是可以启用imp/exp来.导出的参数可以指定需要导出的数据.
    例如 exp a/[email protected] file=c:\tt.dmp tables=(a.ta) query='WHERE ...' 
      

  2. 假如是10g的数据库的话,
    可以使用data pump功能。它比原来的imp/exp的速度要快很多。大约2倍以上。导入的话,大约5-45倍。PARALLEL参数可以用来设置线程数。推荐用这个。
      

  3. 1、在公司端生成csv文件
    2、ftp到服务器端
    3、sqlldr
      

  4. 能否把程序发布在服务器上,然后在存储过程中使用文件操作来解决? 
    又或者,你的程序放在哪里都可以,但是可以启用imp/exp来.导出的参数可以指定需要导出的数据. 
    例如 exp a/[email protected] file=c:\tt.dmp tables=(a.ta) query= 'WHERE ... '  
    -----------------------------------------------------------------------------------
    因为导出的文件不单单面对的是oracle的数据库,因此无法使用Imp/exp去做!如果用存储过程会更慢!我们使用了一种新的方案,没用用ado驱动了,用OCI的驱动,速度可以到5-5.2MB/S,420M的文件生成需要84S!应该是到极限了吧!(单CPU还是100%)
      

aliyun

类似问题 »