Oracle百万级别数据导出!

ccshigenvwa 2012-07-23 02:12:59
现在有个问题是需要一次性导出100W条数据到文件,例如导出txt文件
我采用两种方法读取数据写入txt,
第一种,采用存储过程,分批次读取.
第二种,采用后台拼接成Sql语句的方式读取

测试发现如果每次读取10W条的话,第一种方式初次读取数据会比第二种快,也就是说生成的第一个10W条文件速度要快,

其实两种方式最后所拼接的Sql语句都是一样,只不过一种是采用存储过程,一种是后台程序拼接的方式.这是如何处理?

因为后台程序拼接方式比较适宜不限长度的情况,如果用存储过程的话可能需要考虑传递的参数最大不能过8000这一点很麻烦.

所以请问有没有更好的办法呢?

...全文
856 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
redboy999 2012-07-24
  • 打赏
  • 举报
回复
你这个应该还是属于你读取数据慢了,用存储过程读取速度快一些
ccshigenvwa 2012-07-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
没看到你后面#2的回复,忽略#4

这个参数不超过8000是传入参数还是传出?CLOB类型没有这个限制吧。
[/Quote]
主要是传入参数,就是网上流传的那些oracle的存储过程一样,传入要查询的字段,查询条件等等这些全部作为参数传入,然后得到一个结果集这样的方法.
然后你提到的clob这个参数以前一直没作为传入参数使用过.


顺便贴一下我使用存储过程,主要原因也就是传递参数时候不能突破最大8K限制,说真的还真有可能超过这个限制的哦.


create or replace procedure PROC_COMMPAGESIZE(
tblName in varchar2,--表名
strWhere in varchar2,--查询条件
strGetFields in varchar2, --查询字段
fldName in varchar2,--排序字段
OrderType in number,--排序方式 0升序 1降序
PageIndex in number,--当前页
PageSize in number,--每页显示的记录数
doCount out number,--总记录数
v_cur out pkg_PageQuery.cur_Pagequery)
is
v_sql1 VARCHAR2 (8000); --获取数据的sql语句
v_sql2 VARCHAR2 (8000);
v_pagecount NUMBER; --该条件下记录页数
v_row_start NUMBER; --开始记录
v_row_end NUMBER; --结束记录
v_count number;

begin
v_sql1 := 'select count(1) from ' || tblName;
IF strWhere is not null or strWhere <>'' THEN
v_sql1 := v_sql1 || ' where 1=1 and ' || strWhere;
END IF;

EXECUTE IMMEDIATE v_sql1 INTO doCount;
v_count:=doCount;
--计算数据记录开始和结束
v_pagecount := v_count / PageSize + 1;
v_row_start := (PageIndex - 1) * PageSize + 1;
v_row_end := PageIndex * PageSize;
v_sql2 := 'select rownum RowNo,'|| strGetFields || ' from ' || tblName ;
--v_sql2:='select rownum ro, t.* from ' || tblName || 't ';
v_sql2 := v_sql2 || ' where rownum<=' || v_row_end;

IF strWhere is not null or strWhere <>''
THEN
v_sql2 := v_sql2|| ' and ' || strWhere;
END IF;

if fldName is not null or fldName<>'' then
v_sql2 := v_sql2 || ' order by ' || fldName;
end if;


IF OrderType>0
THEN
v_sql2 := v_sql2 || ' desc';
END IF;

v_sql2 := 'select * from (' || v_sql2 || ') where RowNo >=' || v_row_start;
--DBMS_OUTPUT.put_line (strsql);

OPEN v_cur FOR v_sql2;
END PROC_COMMPAGESIZE;

shiyiwan 2012-07-23
  • 打赏
  • 举报
回复
没看到你后面#2的回复,忽略#4

这个参数不超过8000是传入参数还是传出?CLOB类型没有这个限制吧。
shiyiwan 2012-07-23
  • 打赏
  • 举报
回复
为什么不用sqlloader呢?
AcHerat 2012-07-23
  • 打赏
  • 举报
回复
多段字符串拼接,超過8000就用多個8000來拼接執行。
ccshigenvwa 2012-07-23
  • 打赏
  • 举报
回复
但是作为一个在线的BS程序用户需要的是在线直接导出哦,
现在处理方式也就是后台在跑,只不过是程序在跑然后写入到文件.没有采用etl
还有别的办法么
秋雨飘落 2012-07-23
  • 打赏
  • 举报
回复
用ETL工具,直接写成文件最快啦

3,499

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧